Pandas数据帧中的高级查找



我有一个数据帧,它有两列level1和level2。级别1中的每个帐号都链接到列级别2中的ParentID。

df = pd.DataFrame([[7854568400,489],
[9632588400,126],
[3699633691,189],
[9876543697,987],
[7854568409,396],
[7854567893,897],      
[9632588409,147]],
columns = ['level1','level2'])
df

输出:

level1  level2
0   7854568400  489
1   9632588400  126
2   3699633691  189
3   9876543697  987
4   7854568409  396
5   7854567893  897
6   9632588409  147

对于以";8409";在列";级别1";它们被映射到级别2中错误的ParentID。为了找到正确的ParentID,你需要在级别1中搜索,在那里你替换所有以"结尾的帐户;8409";用";8400";。然后,它将在同一列中找到其等效帐户。在找到匹配的地方,复制列"中的内容;级别2";并将其替换为以";8409";。

在下面的期望输出中7854568409";其级别2从396变为489(取自第0行(9632588409";其级别2从147变为126(取自第1行(。请注意,在列"中没有任何内容被编辑;级别1";仅在";级别2";。

期望输出:

level1  level2
0   7854568400  489
1   9632588400  126
2   3699633691  189
3   9876543697  987
4   7854568409  489
5   7854567893  897
6   9632588409  126

任何关于如何实现这一目标的想法都将是伟大的。

您可能想从确定哪些level1值以8409结尾开始。您可以使用pd.Series.str((命令来完成此操作。

ends_with_8409 = df["level1"].astype( str ).str[-4:] == "8409"

这将创建一个长度与df["level1"]相同的布尔序列,现在您知道了在level2中哪些行需要替换。

现在,为了获得这些行的适当level2值,您可能需要进行合并(尤其是如果数据集很大,这将比映射或应用备选方案快得多(。

df["temp_level1"] = df["level1"].where( ~ends_with_8409, df["level1"].astype( str ).str[0:-4] + "8400" ).astype( int )
final_df = df[ ["temp_level1"] ].merge( df[ ["level1","level2"] ], left_on = "temp_level1", right_on = "level1", how="left" ).drop( columns="temp_level1" )

在这里,我们创建一个列,该列替换以"0"结尾的每个level1值;8409";具有相同的值但以"0"结尾;8400";。然后,将其合并到原始数据帧上,以获得适当的级别2匹配。

final_df[ "level1" ] = final_df[ "level1" ].where( ~ends_with_8409, final_df.astype( str ).str[0:-4] + "8409" ).astype( int )

最后,再次使用ends_with_8409布尔掩码,替换相关的level1值,使得它们以"0"结尾;8409";再一次

>>> final_df
level1  level2
0  7854568400     489
1  9632588400     126
2  3699633691     189
3  9876543697     987
4  7854568409     489
5  7854567893     897
6  9632588409     126

不幸的是,我认为你不能多次使用astype。pd.Series.str((仅在该系列为字符串类型时有效,而合并仅在合并的列为相同类型时有效。这是关于pd.DataFrame.where((.的文档

您可以从dfdf的自合并中更新level2列,在后者(合并右侧(中,level1列更新为正确的帐号:

import pandas as pd
df = pd.DataFrame([[7854568400,489],
[9632588400,126],
[3699633691,189],
[9876543697,987],
[7854568409,396],
[7854567893,897],      
[9632588409,147]],
columns = ['level1','level2'])
df.level2 = df.merge(df.assign(level1 = df.level1.astype(str).str.replace('8409$', '8400', regex=True).astype('int64')), on='level1', how='right')['level2_x']

结果:

level1  level2
0  7854568400     489
1  9632588400     126
2  3699633691     189
3  9876543697     987
4  7854568409     489
5  7854567893     897
6  9632588409     126

最新更新