use*_*984 16 python mysql merge pandas
我正在尝试在两个数据帧之间进行简单的合并.它们来自两个不同的SQL表,其中连接键是字符串:
>>> df1.col1.dtype
dtype('O')
>>> df2.col2.dtype
dtype('O')
Run Code Online (Sandbox Code Playgroud)
我尝试使用以下方法合并它们:
>>> merge_res = pd.merge(df1, df2, left_on='col1', right_on='col2')
Run Code Online (Sandbox Code Playgroud)
内部联接的结果为空,这首先提示我交集中可能没有任何条目:
>>> merge_res.shape
(0, 19)
Run Code Online (Sandbox Code Playgroud)
但是当我尝试匹配单个元素时,我发现这真的很奇怪.
# Pick random element in second dataframe
>>> df2.iloc[5,:].col2
'95498208100000'
# Manually look for it in the first dataframe
>>> df1[df1.col1 == '95498208100000']
0 rows × 19 columns
# Empty, which makes sense given the above merge result
# Now look for the same value as an integer
>>> df1[df1.col1 == 95498208100000]
1 rows × 19 columns
# FINDS THE ELEMENT!?!
Run Code Online (Sandbox Code Playgroud)
因此,列使用'object'dtype定义.将它们作为字符串搜索不会产生任何结果.将它们作为整数搜索会返回结果,我认为这就是为什么合并不起作用的原因..
有什么想法发生了什么?
它几乎就像Pandas转换df1.col1为整数只是因为它可以,即使它应该在匹配时被视为字符串.
(我尝试使用示例数据框复制这个,但是对于小例子,我没有看到这种行为.关于如何找到更具描述性的示例的任何建议也将受到赞赏.)
use*_*984 24
问题是objectdtype具有误导性.我认为这意味着所有项目都是字符串.但显然,在阅读文件时,pandas会将一些元素转换为int,并将剩余部分保留为字符串.
解决方案是确保每个字段都是一个字符串:
>>> df1.col1 = df1.col1.astype(str)
>>> df2.col2 = df2.col2.astype(str)
Run Code Online (Sandbox Code Playgroud)
然后合并按预期工作.
(我希望能有指定的方式dtype的str...)
see*_*spi 10
我遇到了df.col = df.col.astype(str)解决方案无效的案例.原来问题在于编码.
我的原始数据如下所示:
In [72]: df1['col1'][:3]
Out[73]:
col1
0 dustin pedroia
1 kevin youkilis
2 david ortiz
In [72]: df2['col2'][:3]
Out[73]:
col2
0 dustin pedroia
1 kevin youkilis
2 david ortiz
Run Code Online (Sandbox Code Playgroud)
使用.astype(str)合并后仍然没有工作,所以我执行了以下操作:
df1.col1 = df1.col1.str.encode('utf-8')
df2.col2 = df2.col2.str.encode('utf-8')
Run Code Online (Sandbox Code Playgroud)
并找到了差异:
In [95]: df1
Out[95]:
col1
0 b'dustin\xc2\xa0pedroia'
1 b'kevin\xc2\xa0youkilis'
2 b'david\xc2\xa0ortiz'
In [95]: df2
Out[95]:
col2
0 b'dustin pedroia'
1 b'kevin youkilis'
2 b'david ortiz'
Run Code Online (Sandbox Code Playgroud)
在这一点上,我所要做的就是df1.col1 = df1.col1.str.replace('\xa0',' ')在解码的df1.col1变量上运行(即在运行之前.str.encode('utf-8'))并且合并完美.
注意:无论我更换什么,我总是习惯.str.encode('utf-8')检查它是否有效.
另外
使用正则表达式和Spyder IDE中的变量资源管理器为Anaconda我发现了以下区别.
import re
#places the raw string into a list
df1.col1 = df1.col1.apply(lambda x: re.findall(x, x))
df2.col2 = df2.col2.apply(lambda x: re.findall(x, x))
Run Code Online (Sandbox Code Playgroud)
我的df1数据变成了这个(从Spyder复制并粘贴):
['dustin\xa0pedroia']
['kevin\xa0youkilis']
['david\xa0ortiz']
Run Code Online (Sandbox Code Playgroud)
这只是一个略有不同的解决方案.我不知道在什么情况下第一个例子不起作用,第二个例子但是我想提供两个以防万一有人遇到它:)
Fer*_*ras 10
谢谢,@seeiespi ..str.encode('utf-8') 帮助我弄清楚我的字符串需要被剥离,如下所示
20 b'Belize ' ... 0,612
21 b'Benin ' ... 0,546
Run Code Online (Sandbox Code Playgroud)
解决方案是使用条带
df1.col1 = df1.col1.str.strip()
df1.col1 = df1.col1.str.strip()
Run Code Online (Sandbox Code Playgroud)