使用熊猫比较两列

以此为出发点:

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

看起来像是

  one  two three
0   10  1.2   4.2
1   15  70   0.03
2    8   5     0

我想在熊猫中使用类似 if语句的东西。

if df['one'] >= df['two'] and df['one'] <= df['three']:
df['que'] = df['one']

基本上,通过 if语句检查每一行来创建一个新列。

医生说要用 .all但是没有例子..。

576899 次浏览

您可以使用 application ()并执行类似的操作

df['que'] = df.apply(lambda x : x['one'] if x['one'] >= x['two'] and x['one'] <= x['three'] else "", axis=1)

或者你不想用 lambda

def que(x):
if x['one'] >= x['two'] and x['one'] <= x['three']:
return x['one']
return ''
df['que'] = df.apply(que, axis=1)

将每个条件包装在括号中,然后使用 &运算符组合这些条件:

df.loc[(df['one'] >= df['two']) & (df['one'] <= df['three']), 'que'] = df['one']

您可以通过使用 ~(“ not”操作符)反转匹配项来填充不匹配的行:

df.loc[~ ((df['one'] >= df['two']) & (df['one'] <= df['three'])), 'que'] = ''

您需要使用 &~而不是 andnot,因为 &~操作符是逐个元素地工作的。

最终结果:

df
Out[8]:
one  two three que
0  10  1.2   4.2  10
1  15   70  0.03
2   8    5     0

一种方法是使用布尔级数对列 df['one']进行索引。这将为您提供一个新列,其中 True条目的值与 df['one']的相同行相同,而 False的值为 NaN

布尔级数是由 if语句给出的(尽管有必要使用 &而不是 and) :

>>> df['que'] = df['one'][(df['one'] >= df['two']) & (df['one'] <= df['three'])]
>>> df
one two three   que
0   10  1.2 4.2      10
1   15  70  0.03    NaN
2   8   5   0       NaN

如果希望用其他值替换 NaN值,可以在新列 que上使用 fillna方法。我在这里使用了 0而不是空字符串:

>>> df['que'] = df['que'].fillna(0)
>>> df
one two three   que
0   10  1.2   4.2    10
1   15   70  0.03     0
2    8    5     0     0

您可以使用 Np.where。如果 cond是一个布尔数组,而 AB是数组,那么

C = np.where(cond, A, B)

定义 C 等于 A,其中 cond为 True,B,其中 cond为 False。

import numpy as np
import pandas as pd


a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])


df['que'] = np.where((df['one'] >= df['two']) & (df['one'] <= df['three'])
, df['one'], np.nan)

产量

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03  NaN
2   8    5     0  NaN

如果有多个条件,那么可以使用 选择。 例如,如果您希望 df['que']df['one'] < df['two']时等于 df['two'],那么

conditions = [
(df['one'] >= df['two']) & (df['one'] <= df['three']),
df['one'] < df['two']]


choices = [df['one'], df['two']]


df['que'] = np.select(conditions, choices, default=np.nan)

产量

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03   70
2   8    5     0  NaN

如果我们可以假设 df['one'] >= df['two']df['one'] < df['two']是 假,那么条件和选择可以简化为

conditions = [
df['one'] < df['two'],
df['one'] <= df['three']]


choices = [df['two'], df['one']]

(如果 df['one']df['two']含有 NaNs,这个假设可能不成立。)


请注意

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

定义一个带有字符串值的 DataFrame。因为它们看起来是数字的,所以最好将这些字符串转换为浮点数:

df2 = df.astype(float)

但是,这会改变结果,因为字符串是逐字符比较的,而浮点数是数字比较的。

In [61]: '10' <= '4.2'
Out[61]: True


In [62]: 10 <= 4.2
Out[62]: False

可以对列或整个数据框架使用 .equals

df['col1'].equals(df['col2'])

如果它们相等,该语句将返回 True,else False

我认为最接近 OP 的直觉是一个内联 if 语句:

df['que'] = (df['one'] if ((df['one'] >= df['two']) and (df['one'] <= df['three']))

如果需要从数据框中检查多个条件,并在不同的列中输出特定的选项,则使用 np.select

conditions=[(condition1),(condition2)]
choices=["choice1","chocie2"]


df["new column"]=np.select=(condtion,choice,default=)

注意: 条件 No 和选项 No 应该匹配,如果对于两个不同的条件有相同的选项,则在选项中重复文本

使用 lambda 表达式:

df[df.apply(lambda x: x['col1'] != x['col2'], axis = 1)]

我想为那些试图比较具有 NaN值的两列中值的相等性的人添加这个答案,并且当两个值都是 NaN时得到 False。根据定义,NaN!= NaN(见: Isnan (value)不等于 value = = numpy.nan?)。

如果希望两个 NaN比较返回 True,可以使用:

df['compare'] = (df["col_1"] == df["col_2"]) | (df["col_1"].isna() & df["col_2"].isna())

你可以使用 Series 方法 where:

df['que'] = df['one'].where((df['one'] >= df['two']) & (df['one'] <= df['three']))

结果:

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03  NaN
2   8    5     0  NaN

如果要比较两个数据帧列中的值,可以使用 eq():

df['one'].eq(df['two'])

eval()

df.eval("one == two")

如果你想把它简化成一个布尔值,调用 all():

df['one'].eq(df['two']).all()
# or
df.eval("one == two").all()

这是一个比 equals()更“健壮”的检查,因为为了使 equals()返回 True,列 dtype 也必须匹配。因此,如果一个列是 dtype int,另一个是 dtype float,即使值相同,equals()也会返回 False,而 eq().all()/eval().all()只是比较列元素。

如果您的列包含 NaN 值,那么使用以下内容(它利用了 NaN != NaN这一事实) :

df.eval("one == two or one != one").all()

对于 OP 的具体问题,由于模式是“ A < B 和 B < C”,因此可以使用 between():

cond = df['one'].between(df['two'], df['three'])
df['que'] = np.where(cond, df['one'], np.nan)