熊猫从 df 中提取行,其中 df['col'] 值与 df2['col'] 值匹配



发现这个很难,想看看你是否可以提供帮助,请:

我有两个dfdfAdfB。每个列都有一个telnumfiledatetime列,但只有dfA包含name列,只有dfA具有完整的电话号码字符串值,不像dfB有时有部分完整的电话号码,最多n位数x,例如有时缺少国际呼叫代码, 其他时候,存在"0"而不是 int'l 调用代码,而其他时候,国际呼叫代码或前导"0"都不存在。

dfA还包含比dfB更多的数据(<10 行),但在两者之间有完整的timestampfiletelnum列,始终分别带有日期时间和字符串值(即使如上所述dfB['telnum']并不完全完整)。

我想做的是从dfA中提取dfB['telnum']匹配dfA['telnum']的行,但由于dfB['telnum']并不总是完整的,所以我也需要检查匹配项作为dfA['telnum']的子字符串。

我希望结果是dfResult的,但返回的结果在左侧有dfA值,在右侧有dfB值,以便我可以看到不同的filedatetime值。

有什么想法吗?

编辑:

我想我需要一个内部合并,例如

pandas.merge(dfA, dfB, on='telnum', how='inner')

但是,由于字符串telnumdfB['telnum']并不总是完整的,因此结果不完整。如何通过检查dfB['telnum']是否也是dfA['telnum']的子字符串来获得两者之间匹配的内容?

在执行任何复杂的连接之前,您需要清理数据。 我不确定您所在国家/地区的情况如何,但在我的国家/地区,如果您删除国际前缀或前导零,电话号码将变为 9 位数字长。

以下是我建议你做的:

  1. 清理您的"telnum"列:
def remove_non_numbers(string):
result = ""
for char in string:
if char.isnumeric():
result += char
return result
# Do this for both dataframes just in case
df["telnum"] = df["telnum"].apply(remove_non_numbers)
  1. 删除最后 9 个之前的任何数字:
def limit9(string):
if len(string) > 9:
return string[-9:]
return string
# Do this for both dataframes
df["telnum"] = df["telnum"].apply(limit9)
  1. 现在您可以尝试合并清理后的DF:
dfResult = pd.merge(dfA, dfB, on='telnum', how='inner')

祝你好运!让我知道它是否有效。

由于您没有根据描述提供任何示例输入或输出,因此我在这里进行尝试。这是一个多方面的问题,根据您的电话号码的外观,可以有很多方法。

让我在这里有两个数据帧(跳过您的其他列):dfAdfB

dfA:

telnum
0   0049123456789
1  00919444454555
2   0092789742893

dfB:

telnum
0    123456789
1  09444454555

首先,让我们清理dfB中的数字。dfB可以有以下数字:

  • 带有ISD代码的数字 - 如00918888888888
  • 前面有 0 的数字08888888888
  • 仅数字 -8888888888

我正在剥离每个以 0 开头的数字。因此,任何具有国际代码0091成为091的东西,或者具有091并成为91,并且具有0888888888成为888888888。这样做是,由于您的 dfA 具有带有 ISD 代码的完整编号,我认为该代码不符合00xxNNNNNNNN格式,因此应该很容易找到子字符串匹配。

dfB['telnum'] = dfB['telnum'].apply(lambda x : x[1:] if x.startswith("0") else x)

dfB 现在看起来像(请注意,第一个出现的 0 已被剥离):

telnum  
0   123456789 
1  9444454555 

从 dfB 中获取所有数字并将它们转换为列表:

tempList = dfB['telnum'].tolist()

现在在另一个数据帧中查找匹配项:

dfA[dfA.telnum.str.contains('|'.join(tempList))]

您现在应该得到:

telnum
0   0049123456789
1  00919444454555

因此,您已经找到了匹配的那些数字。现在,您可以继续处理这些行,并与其他列或任何您想要的内容执行必要的联接。

最新更新