我有以下数据框
df = pd.DataFrame({
'Column_1': ['Position', 'Start', 'End', 'Position'],
'Original_1': ['Open', 'Barn', 'Grass', 'Bubble'],
'Latest_1': ['Shut', 'Horn', 'Date', 'Dinner'],
'Column_2': ['Start', 'Position', 'End', 'During'],
'Original_2': ['Sky', 'Hold', 'Car', 'House'],
'Latest_2': ['Pedal', 'Lap', 'Two', 'Force'],
'Column_3': ['Start', 'End', 'Position', 'During'],
'Original_3': ['Leave', 'Dog', 'Block', 'Hope'],
'Latest_3': ['Sear', 'Crawl', 'Enter', 'Night']
})
对于“位置_1”,“列_2”或“列_3”中单词“位置”的每个实例,我想捕获“ Original_1”,“ Original_2”,“ Original_3”中的关联值并将它们分配给新列“ Original_Values”。
以下代码可以完成此操作,但只能逐列进行。
df['Original_Value1'] = df.loc[df['Column_1'] == 'Position', 'Original_1']
df['Original_Value2'] = df.loc[df['Column_2'] == 'Position', 'Original_2']
df['Original_Value3'] = df.loc[df['Column_3'] == 'Position', 'Original_3']
有没有一种方法可以重新创建上面的代码,从而使它遍历整个数据帧(而不是按指定的列)?
我希望创建一个具有以下结果的列(“ Original_values”):
0 Open
1 Hold
2 Block
3 Bubble
Name: Original_Values, dtype: object
答案 0 :(得分:2)
使用df.apply()的一种方式:
def choose_orig(row):
if row['Column_1'] == 'Position':
return row['Original_1']
elif row['Column_2'] == 'Position':
return row['Original_2']
elif row['Column_3'] == 'Position':
return row['Original_3']
return ''
df['Original_Values'] = df.apply(choose_orig, axis=1)
axis=1
的{{1}}参数导致对数据帧的每一行调用一次df.apply()
函数。
请注意,当没有列与单词choose_orig()
匹配时,它将使用空字符串''
的默认值。
答案 1 :(得分:2)
如何使用前3个cols创建遮罩(或指定它们的名称),然后将其与6s到9 cols中的值相乘(或指定它们的名称)。然后取max()值删除nan。
df['Original_Values'] = ((df.iloc[:,:3] == 'Position') * df.iloc[:,6:9].values).max(1)
print(df['Original_values'])
返回:
0 Open
1 Hold
2 Block
3 Bubble
Name: Original_Value, dtype: object
答案 2 :(得分:0)
这是通过一些堆叠进行操作的一种愚蠢的方法,如果您的df
很大并且需要避免使用axis=1
,这可能会更好。
'Original'
列df
。 代码如下:
import re
mask_list = ['Column_1', 'Column_2', 'Column_3']
val_list = ['Original_1', 'Original_2', 'Original_3']
idx = df[mask_list].stack()[df[mask_list].stack() == 'Position'].index.tolist()
idx = [(x , re.sub('(.*_)', 'Original_', y)) for x, y in idx]
df['Original_Values'] = df[val_list].stack().reindex(idx).reset_index(level=1).drop(columns='level_1')
df
现在是:
Column_1 Column_2 Column_3 ... Original_Values
0 Position Start Start ... Open
1 Start Position End ... Hold
2 End End Position ... Block
3 Position During During ... Bubble
如果在'Position'
的任何列中均未找到mask_list
,则Original_Values
变为该行的NaN
。如果需要将其缩放到更多列,只需将它们添加到mask_list
和val_list
。