根据另一列

时间:2018-04-15 00:23:21

标签: python pandas

我有兴趣将文本标记添加到Pandas数据框中的新列。以下示例有效但我得到了复制警告,我不完全理解在这种情况下是否应该忽略它。

DataFrame只有一个字符或是一个空字符串:

In [1]: import pandas as pd

In [2]: df=pd.DataFrame({('A'):['x','','x',''], ('B'):['x','x','','']})

In [3]: df
Out[3]:
   A  B
0  x  x
1     x
2  x
3

创建一个名为“msg”的新列

In [4]: df['msg'] = ''

In [5]: df
Out[5]:
   A  B msg
0  x  x
1     x
2  x
3

如果'A'不是空字符串

,请将'msg'列设置为'red'
In [6]: df['msg'][df['A'] != ''] = 'red;'

In [7]: df
Out[7]:
   A  B  msg
0  x  x  red;
1     x
2  x     red;
3

根据'B'列值

连接'蓝色'
In [8]: df['msg'][df['B'] != ''] += 'blue;'

In [9]: df
Out[9]:
   A  B       msg
0  x  x  red;blue;
1     x     blue;
2  x         red;
3

或者,我发现使用 numpy.where 产生了所需的结果。在熊猫中这样做的正确方法是什么?

import numpy as np

df['msg'] += np.where(df['A'] != '','green;', '')

更新:4/15/2018

进一步考虑,在某些情况下保留原始DataFrame中的数据会很有用,但仍会附加标签(本例中为“颜色”)。来自@COLDSPEED的回答让我得到以下结论(在这种情况下,将'blue;'更改为'blue:'并保留列'B'数据以包含在标记中):

df['msg'] = (v.where(df.applymap(len) > 0, '') + 
             df.where(df[['B']].applymap(len)>0,'')).agg(''.join, axis=1)


   A  B         msg
0  x  x  red;blue:x
1     x      blue:x
2  x           red;
3

3 个答案:

答案 0 :(得分:4)

如果您事先了解自己的颜色,可以使用DataFrame.wherestr.join进行遮罩来完成此操作。

v = pd.DataFrame(
     np.repeat([['red;', 'blue;']], len(df), axis=0), 
     columns=df.columns, 
     index=df.index
) 
df['msg'] = v.where(df.applymap(len) > 0, '').agg(''.join, axis=1)

df
   A  B        msg
0  x  x  red;blue;
1     x      blue;
2  x          red;
3              

答案 1 :(得分:4)

使用pandas.DataFrame.dot
特别注意我将数组的dtype设置为object。否则dot无法正常工作。

a = np.array(['red', 'blue;'], object)

df.assign(msg=df.astype(bool).dot(a))

   A  B        msg
0  x  x  red;blue;
1     x      blue;
2  x          red;
3                 

答案 2 :(得分:4)

您可以使用dotreplace

(df!='').dot(df.columns).replace({'A':'red;','B':'blue;'},regex=True)
Out[379]: 
0    red;blue;
1        blue;
2         red;
3             
dtype: object

#df['msg']=(df!='').dot(df.columns).replace({'A':'red;','B':'blue;'},regex=True)