1

我有以下数据框

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']
})

对于单词 Position 在“Column_1”、“Column_2”或“Column_3”中的每个实例,我想捕获“Original_1”、“Original_2”、“Original_3”中的关联值并将它们分配给名为“原始值'。

下面的代码可以做到这一点,但只能在逐列的基础上。

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
4

3 回答 3

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参数df.apply()导致choose_orig()函数为数据帧的每一行调用一次。

请注意'',当没有任何列与单词匹配时,这使用空字符串的默认值'Position'

于 2018-06-20T18:20:42.263 回答
2

How about creating a mask with the first 3 cols (or specify the name of them) and multiply it with the values in cols 6 to 9 (or specify the names of them). Then take max() value to remove nan.

df['Original_Values'] = ((df.iloc[:,:3] == 'Position') * df.iloc[:,6:9].values).max(1)

print(df['Original_values'])

Returns:

0      Open
1      Hold
2     Block
3    Bubble
Name: Original_Value, dtype: object
于 2018-06-20T19:13:49.407 回答
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_listOriginal_Values则变为NaN该行。如果您需要将其扩展到更多列,只需将它们添加到mask_listval_list

于 2018-06-20T18:52:56.567 回答