我有一个DataFrame df
:
A B
a 2 2
b 3 1
c 1 3
我想根据以下标准创建一个新列:
如果行A == B: 0
如果行A > B: 1
如果行A < B: -1
所以给出上表,它应该是:
A B C
a 2 2 0
b 3 1 1
c 1 3 -1
对于我if else
的典型np.where(df.A > df.B, 1, -1)
个案例,pandas是否提供了一个特殊的语法来一步解决我的问题(无需创建3个新列然后合并结果)?
答案 0 :(得分:68)
正式确定上述一些方法:
创建一个对数据帧的行进行操作的函数,如下所示:
def f(row):
if row['A'] == row['B']:
val = 0
elif row['A'] > row['B']:
val = 1
else:
val = -1
return val
然后将其应用于传递axis=1
选项的数据框:
In [1]: df['C'] = df.apply(f, axis=1)
In [2]: df
Out[2]:
A B C
a 2 2 0
b 3 1 1
c 1 3 -1
当然,这不是矢量化的,因此在缩放到大量记录时性能可能不会那么好。不过,我认为它更具可读性。特别是来自SAS背景。
答案 1 :(得分:13)
df.loc[df['A'] == df['B'], 'C'] = 0
df.loc[df['A'] > df['B'], 'C'] = 1
df.loc[df['A'] < df['B'], 'C'] = -1
使用索引很容易解决。第一行代码读取如此,如果列'A'等于列'B',则创建并设置列'C'等于0.注意我没有尝试运行它,因此代码可能需要修改如下所示,df.loc [(df ['A'] == df ['B']),'C'] = 0,它在条件周围使用括号。
答案 2 :(得分:8)
对于这种特殊关系,您可以使用np.sign
:
>>> df["C"] = np.sign(df.A - df.B)
>>> df
A B C
a 2 2 0
b 3 1 1
c 1 3 -1
答案 3 :(得分:2)
让我们说一个以上是您的原始数据框,并且您想添加一个新列'old'
如果年龄大于50岁,则我们认为年龄更大=是,否则为False
步骤1:获取年龄大于50的行的索引
row_indexes=df[df['age']>=50].index
第2步:
使用.loc我们可以为列
分配新值
df.loc[row_indexes,'elderly']="yes"
年龄小于50岁的人
row_indexes=df[df['age']<50].index
df[row_indexes,'elderly']="no"
答案 4 :(得分:1)
当您有多个if
时
条件,numpy.select
是必经之路:
In [4102]: import numpy as np
In [4098]: conditions = [df.A.eq(df.B), df.A.gt(df.B), df.A.lt(df.B)]
In [4096]: choices = [0, 1, -1]
In [4100]: df['C'] = np.select(conditions, choices)
In [4101]: df
Out[4101]:
A B C
a 2 2 0
b 3 1 1
c 1 3 -1
答案 5 :(得分:-1)
对于大型数据集,行式操作可能需要很长时间。更好的方法是找到与条件匹配的行的索引,然后将值分配给这些行的所需列('C')。
df.loc[df['A'] == df['B'], 'C'] = 0
df.loc[df['A'] > df['B'], 'C'] = 1
df.loc[df['A'] < df['B'], 'C'] = -1