我有一个来自 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'] = ???
答案 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