发现这一难题很困难,希望您能帮上忙,
我有两个df
,dfA
和dfB
。每个字段中都有一个telnum
,file
和datetime
列,但是只有dfA
包含一个name
列,并且只有dfA
具有完整的电话不同于dfB
的数字字符串值,该数字字符串值有时具有部分完整的电话号码,最高为x
个数字,例如有时,缺少国际调用代码,有时提供的是'0'而不是国际调用代码,而另一些时候,既没有国际调用代码也没有前导'0'。
n
还包含比dfA
(<10行)更多的数据,但是在两者之间有完整的dfB
,timestamp
和file
列总是分别带有日期时间和字符串值(即使telnum
并不完全如上所述)。
我想做的是从dfB['telnum']
匹配dfA
的{{1}}中提取行,但是由于dfB['telnum']
并不总是完整,因此我需要检查匹配dfA['telnum']
的子字符串。
我希望结果为dfB['telnum']
,但是返回的结果的左侧为dfA['telnum']
,右侧为dfResult
,这样我可以看到不同的{{1} }和dfA
值。
有什么想法吗?
编辑:
我认为我需要一个内部合并,例如
dfB
但是,由于file
并不总是完整的datetime
字符串,因此结果不完整。如何通过检查pandas.merge(dfA, dfB, on='telnum', how='inner')
是否也是dfB['telnum']
的子字符串来获得两者之间的匹配项?
答案 0 :(得分:1)
在执行任何复杂的联接之前,您需要清除数据。 我不确定您所在的国家/地区情况如何,但是在我的国家/地区,如果删除国际前缀或前导零,则电话号码会变成9位数字。
这是我建议您做的事情:
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)
def limit9(string):
if len(string) > 9:
return string[-9:]
return string
# Do this for both dataframes
df["telnum"] = df["telnum"].apply(limit9)
dfResult = pd.merge(dfA, dfB, on='telnum', how='inner')
祝你好运!让我知道它是否有效。
答案 1 :(得分:0)
由于您没有提供任何示例输入或输出,因此根据说明,我在这里尝试。这是一个多重问题,取决于您的电话号码的外观,可以有很多方法。
在这里让我有两个数据框(跳过其他列):dfA
和dfB
。
dfA:
telnum
0 0049123456789
1 00919444454555
2 0092789742893
dfB:
telnum
0 123456789
1 09444454555
首先,让我们清理dfB
中的数字。 dfB
可以包含以下数字:
00918888888888
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
因此,您找到了与之匹配的数字。现在,您可以继续执行这些行,并与其他列或所需的任何内容进行必要的连接。