我有一个类似于:
df = pd.DataFrame([{'v1':'a', 'v2':'b', 'v3':'1'},
{'v1':'2', 'v2':'c', 'v3':'d'}])
或
v1 v2 v3
0 a b 1
1 2 c d
当列/行的内容为“1”、“2”或“3”时,我希望用所示列中的相应项替换其内容。也就是说,在第一行中,column
DataFrame
有值v3
,所以我想用column"1"
中第一个元素的值替换它对两排都这样做,我应该得到: v1 v2 v3
0 a b a
1 c c d
我可以使用以下代码来完成此操作:
for i in range(3):
for j in range(3):
df.loc[df['v%d' % (i+1)]==('%d' % (j+1)),'v%d' % (i+1)]= \
df.loc[df['v%d' % (i+1)]==('%d' % (j+1)),'v%d' % (j+1)]
有没有不那么麻烦的方法?
最佳答案
df.apply(lambda row: [row['v'+v] if 'v'+v in row else v for v in row], 1)
此迭代遍历每一行,并用名为“cc>”列中的值替换任何值
v
,如果该列存在,否则不会更改值。输出:
v1 v2 v3
0 a b a
1 c c d
请注意,这不会将替换仅限于数字。例如,如果有一个名为
'v'+v
的列,它将用该行中'va'
列中的值替换包含“a”的所有单元格。要限制可以替换的行,可以定义可接受列名的列表。例如,假设您只想替换列'va'
:acceptable_columns = ['v1']
df.apply(lambda row: [row['v'+v] if 'v'+v in acceptable_columns else v for v in row], 1)
输出:
v1 v2 v3
0 a b a
1 2 c d
编辑
有人指出,如果数据帧中有非字符串类型,则上面的答案会引发错误。可以通过将每个单元格值显式转换为字符串来避免此问题:
df.apply(lambda row: [row['v'+str(v)] if 'v'+str(v) in row else v for v in row], 1)
下面的原始(不正确)答案
请注意,下面的答案仅适用于要替换的值位于对角线上的情况(在示例中是这种情况,但这不是所问的问题……我的错)
你可以用熊猫的
v1
方法和numpy的replace
方法:首先选择要替换的值,这些值将是数据帧长度的数字1:
to_replace = [str(i) for i in range(1,len(df)+1)]
然后选择每个应替换为的值,这些值将是数据帧的对角线:
import numpy as np
replace_with = np.diag(df)
现在您可以进行实际的替换:
df.replace(to_replace, replace_with)
它给出:
v1 v2 v3
0 a b a
1 c c d
当然,如果你想把这整件事当作一条线:
df.replace([str(i) for i in range(1,len(df)+1)], np.diag(df))
如果要进行替换,请将
diag
关键字arg添加到inplace=True
。关于python - 如何从其他指示的列替换DataFrame的元素,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45146977/