【问题标题】:Conditionally replacing column values in pandas with values from a different dataframe有条件地将 pandas 中的列值替换为来自不同数据帧的值
【发布时间】:2018-11-02 12:35:53
【问题描述】:

我有两个 csv,当作为数据帧读取时,看起来像这样:

df:

   TargetIndex Current1 Current2 Current3
0            0       'D'      'D'      'G'
1            2        0       'E'      'F'
2            0       'A'      'E'      'F'
3            1        0        0        0
4            0       'A'       0       'A'
5            3       'G'       0        0
6            2       'F'      'E'       0
7            4        0        0        0


df2:

    TargetIndex Target1 Target2 Target3
0             1      'A'     'A'     'A'
1             2      'B'     'B'     'B'
2             3      'C'     'C'     'C'
3             4      'A'     'B'     'C'

我要做的只是将Current 列中的0 值替换为Target 列中的值。但是,仅在 TargetIndex 值不是 0 的行上。

诚然,我对 Python 非常缺乏经验,通常我会在 excel 中使用附加列和 LOOKUP 函数的组合来解决这个问题,所以我有点挣扎。

到目前为止,我所做的是在这里阅读了一堆线程,并尝试了 .loc.isin.replace.map 的各种用法,但我发现它很难应用TargetIndex != 0CurrentX == 0的条件。

我发现困难的另一件事是首先使用第二个数据框,我已经尝试将它变成.dict,但成功有限,我确实知道它是如何工作的,我不能完全应用它。

我确实设法将预期的结果逆向工程为以下意大利面条代码:

df['Target1'] = df['TargetIndex'].map(df2.set_index('TargetIndex')['Target1'])
df['Target2'] = df['TargetIndex'].map(df2.set_index('TargetIndex')['Target2'])
df['Target3'] = df['TargetIndex'].map(df2.set_index('TargetIndex')['Target3'])
S1 = df.Current1 == 0
S2 = df.Current2 == 0
S3 = df.Current3 == 0
df.loc[S1, 'Current1'] = df['TargetIndex']
df.loc[S2, 'Current2'] = df['TargetIndex']
df.loc[S3, 'Current3'] = df['TargetIndex']
df.replace({'Current1': { 1 : 'A', 2 : 'B', 3 : 'C', 4 : 'A'}}, inplace=True)
df.replace({'Current2': { 1 : 'A', 2 : 'B', 3 : 'C', 4 : 'B'}}, inplace=True)
df.replace({'Current3': { 1 : 'A', 2 : 'B', 3 : 'C', 4 : 'C'}}, inplace=True)
df.drop(df.columns[[4, 5, 6]], axis=1, inplace=True)

这确实产生了预期的结果:

df:

   TargetIndex Current1 Current2 Current3
0            0       'D'      'D'      'G'
1            2       'B'      'E'      'F'
2            0       'A'      'E'      'F'
3            1       'A'      'A'      'A'
4            0       'A'       0       'A'
5            3       'G'      'C'      'C'
6            2       'F'      'E'      'B'
7            4       'A'      'B'      'C'

但是,它需要手动输入要替换的内容,当 df2 csv 包含 5000 多行时,这不是很有效或不可行。 必须有更好的方法来做到这一点,我只是没有正确看到或理解,所以我想我不妨问问。

【问题讨论】:

  • 最后 3 列中的零是字符串还是整数?

标签: python pandas csv replace lookup


【解决方案1】:

如果列数相同,您可以使用:

#create index with 
df1 = df1.set_index('TargetIndex')
df2 = df2.set_index('TargetIndex')
#set same columns names for align data
df2.columns = df1.columns

#replace 0 with NaNs and replace NaNs by df2
df = df1.mask(df1 == 0).combine_first(df2)
print (df)
            Current1 Current2 Current3
TargetIndex                           
0                'D'      'D'      'G'
0                'A'      'E'      'F'
0                'A'      NaN      'A'
1                'A'      'A'      'A'
2                'B'      'E'      'F'
2                'F'      'E'      'B'
3                'G'      'C'      'C'
4                'A'      'B'      'C'

如果顺序很重要,请添加reset_index 进行排序:

df1 = df1.reset_index().set_index('TargetIndex')
df2 = df2.set_index('TargetIndex')
df2.columns = df1.columns[1:]

df = (df1.mask(df1 == 0)
        .combine_first(df2)
        .sort_values('index')
        .drop('index', 1)
        .reset_index()
        .fillna(0))
print (df)
   TargetIndex Current1 Current2 Current3
0            0      'D'      'D'      'G'
1            2      'B'      'E'      'F'
2            0      'A'      'E'      'F'
3            1      'A'      'A'      'A'
4            0      'A'        0      'A'
5            3      'G'      'C'      'C'
6            2      'F'      'E'      'B'
7            4      'A'      'B'      'C'

【讨论】:

  • 谢谢,这解决了我的问题!这也太快了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 2019-02-12
  • 2016-04-29
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
相关资源
最近更新 更多