根据其他行和列更改单元格值

时间:2021-02-08 22:42:54

标签: python pandas dataframe

我有一个来自 SQL 查询的名为 Result 的数据框:

Loc  ID   Bank
1    23   NULL
1    24   NULL
1    25   NULL
2    23   6
2    24   7
2    25   8

Loc == 1 相同时,我试图将 Loc == 2 Bank 的值设置为等于 ID 的 Bank,结果:

Loc  ID   Bank
1    23   6
1    24   7
1    25   8
2    23   6
2    24   7
2    25   8

这是我使用代码的地方,我知道结尾非常简单,我无法围绕一个不涉及迭代每一行(9000~)的解决方案。

result.loc[(result['Loc'] == '1'), 'bank'] = ???

3 个答案:

答案 0 :(得分:0)

你可以试试这个。它使用 map() 从 ID 中获取值。

for_map = df.loc[df['Loc'] == 2].set_index('ID')['Bank'].squeeze().to_dict()
df.loc[df['Loc'] == 1,'Bank'] = df.loc[df['Loc'] == 1,'Bank'].fillna(df['ID'].map(for_map))

答案 1 :(得分:0)

Why not 使用 pandas.MultiIndex ?

共性

# Arguments,
_0th_level = 'Loc'
merge_key  = 'ID'
value_key  = 'Bank'  # or a list of colnames or `slice(None)` to propagate all columns values.
src_key    = '2'
dst_key    = '1'
# Computed once for all,
df         = result.set_index([_0th_level, merge_key])
df2        = df.xs(key=src_key, level=_0th_level, drop_level=False)
df1_       = df2.rename(level=_0th_level, index={src_key: dst_key})

第一种(幼稚)方法

df.loc[df1_.index, value_key] = df1_
# to get `result` back : df.reset_index()

第二种(稳健的)方法

如图所示,如果有一个或多个缺失的标签 [...],第一种方法可能是 illegal(自 Pandas 1.0.0 版起)。

因此,如果您必须确保源和目标都存在索引,则以下仅在共享 ID 上执行此工作。

df1 = df.xs(key=dst_key, level=_0th_level, drop_level=False)
idx = df1.index.intersection(df1_.index)  # <-----
df.loc[idx, value_key] = df1_.loc[idx, value_key]

答案 2 :(得分:0)

您可以在 ID 上对数据帧进行自我合并,然后过滤等于 2 的行:

(
    df.merge(df, on="ID")
    .loc[lambda df: df.Loc_y == 2, ["Loc_x", "ID", "Bank_y"]]
    .rename(columns=lambda x: x.split("_")[0] if "_" in x else x)
    .astype({"Bank": "Int8"})
    .sort_values("Loc", ignore_index=True)
)

     Loc    ID  Bank
0     1     23  6
1     1     24  7
2     1     25  8
3     2     23  6
4     2     24  7
5     2     25  8

你也可以堆叠/取消堆叠,但如果你有重复的索引,这会失败:

(
    df.set_index(["Loc", "ID"])
    .unstack("Loc")
    .bfill(1)
    .stack()
    .reset_index()
    .reindex(columns=df.columns)
)

    Loc     ID  Bank
0     1     23  6.0
1     2     23  6.0
2     1     24  7.0
3     2     24  7.0
4     1     25  8.0
5     2     25  8.0
相关问题