使用条件从索引 1 开始替换数据框中的所有列

Posted

技术标签:

【中文标题】使用条件从索引 1 开始替换数据框中的所有列【英文标题】:Replace all columns in dataframe from index 1 onwards using conditions 【发布时间】:2021-04-01 08:57:34 【问题描述】:

我想根据第一列替换第一列之后的数据框中的列。假设我们有:

df = 'Z':  ['1', '0', '1', '1', '0'],
        'A': ['1', '1', '1', '0', '0'],
        'B': ['0', '0', '1', '0', '0'],
        'C': ['1', '0', '0', '0', '`1']

df = pd.DataFrame (df, columns = ['Z','A','B','C'])

df

我想用1 IF column = Z ELSE 0 替换列。

期望的结果如下:

df2 = 'Z':  ['1', '0', '1', '1', '0'],
        'A': ['1', '0', '1', '0', '1'],
        'B': ['0', '1', '1', '0', '1'],
        'C': ['1', '1', '0', '0', '`0']

df2 = pd.DataFrame (df2, columns = ['Z','A','B','C'])

df2

问题是我有 60 列(A、B、C、D、.....),我希望能够同时完成它们。

【问题讨论】:

1 if z = COLUMN ELSE 0. 是什么意思? IF 列 = Z THEN 1 ELSE 0 什么是列? IF column A = column Z THEN 1 ELSE 0 但我需要它一次性用于所有列,因为我有 60 个。以上只是提供上下文 所有的列都是数字吗? 【参考方案1】:

使用numpy broadcasting:

# Z column
z = df.iloc[:, 0].values

# rest of columns
rest = df.iloc[:, 1:].values

# do comparison and set values
df.iloc[:, 1:] = (z[:, None] == rest).astype(int)

print(df)

输出

   Z  A  B  C
0  1  1  0  1
1  0  0  1  1
2  1  1  1  0
3  1  0  0  0
4  0  1  1  0

如果您需要新的 DataFrame,请执行以下操作:

z = df.iloc[:, 0].values
rest = df.iloc[:, 1:].values

df2 = pd.DataFrame(data=(z[:, None] == rest).astype(int), columns=df.columns[1:], index=df['Z']).reset_index()
print(df2)

输出

   Z  A  B  C
0  1  1  0  1
1  0  0  1  1
2  1  1  1  0
3  1  0  0  0
4  0  1  1  0

【讨论】:

非常感谢@Dani Masejo!这正是我想要的! Majeso - 假设 A、B 或 C 中的某些值包括 Nan,我希望它们保持为 Nan - 为此我需要在代码中添加什么? @JoeSmart 谁有 nan 值 z 或其他列? Z 没有 NaN。 A,B,C 可能有一些 NaN。如果他们确实有 NaN,我希望他们保持原样。上面使用的方法将NaN转换为0 @JoeSmart 只需将它们设置回 nan【参考方案2】:

您可以使用DataFrame.eqaxis=0Z 列与其余列进行比较,然后将join 生成的数据框与Zmask 列的NaN 值进行比较:

df[['Z']].join(df.drop('Z', 1).eq(df['Z'], axis=0).astype(int)).mask(df.isna())

   Z  A  B  C
0  1  1  0  1
1  0  0  1  1
2  1  1  1  0
3  1  0  0  0
4  0  1  1  0

【讨论】:

【参考方案3】:

我认为有一种简单的方法可以通过检查相等性并转换为整数来做到这一点。

z = df["Z"]
others = [c for c in df.columns if c != "Z"] # all columns but 'Z'

df[others] = df[others].transform(lambda x : x.eq(z).astype(int))

输出:

   Z  A  B  C
0  1  1  0  1
1  0  0  1  1
2  1  1  1  0
3  1  0  0  0
4  0  1  1  0

请注意,有一种方法可以保留 NA,但您必须使用 pandas 数据类型,请参阅 nullable data types 和 text data types。

【讨论】:

以上是关于使用条件从索引 1 开始替换数据框中的所有列的主要内容,如果未能解决你的问题,请参考以下文章

从数据框中的列中采样唯一行而不进行替换

如何使用 tidyr::replace_na 替换数据框中的所有 NA? [复制]

如何用同一数据框中其他列的实际列值替换一列中的字符串值?

Pandas DataFrame:根据条件替换列中的所有值

根据列中的条件对数据框中的行进行子集/过滤

将列中的 NA 替换为相邻列中的值