有条件地用来自不同数据框的值替换 pandas 中的列值
Conditionally replacing column values in pandas with values from a different dataframe
我有两个 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 != 0
和 CurrentX == 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 多行时,这不是很有效或不可行。
必须有更好的方法来做到这一点,我只是没有正确地看到或理解,所以我想我不妨问一下。
如果列数相同,您可以使用:
#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'
我有两个 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 != 0
和 CurrentX == 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 多行时,这不是很有效或不可行。 必须有更好的方法来做到这一点,我只是没有正确地看到或理解,所以我想我不妨问一下。
如果列数相同,您可以使用:
#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'