Pandas Left Merge with xlsx with CSV 在输出中产生空值列
Posted
技术标签:
【中文标题】Pandas Left Merge with xlsx with CSV 在输出中产生空值列【英文标题】:Pandas Left Merge with xlsx with CSV producing null value columns in output 【发布时间】:2015-12-29 14:22:46 【问题描述】:我使用 Python 3.4、Pandas 0.16.2 和 Jupyter Notebook 作为我的 IDE。
我正在导入以下两个数据框:
Lookup = pd.read_excel("LookupMergeOutput.xlsx")
Concatenated = pd.read_csv('Concatenated.csv', error_bad_lines = False, na_values='', iterator=True, chunksize=1000)
data = pd.concat([chunk for chunk in Concatenated], ignore_index=True)
数据
查找数据框规范:23353 行 8; 8列
Columns: Dtype:
LOGINNAME object
FIRSTNAME object
LASTNAME object
ID_y int64
CREATEUSERID int64
REVISIONUSERID int64
BEGINDATE object
ENDDATE object
data 数据框规格:23653 行; 667列
此数据框中合并的感兴趣的列是REFERENCE_ID
data.REFERENCE_ID.dtype
作为“对象”
要合并的列是 ID_y
和 REFERENCE_ID
(在 data 数据框中)。 Lookup 中的列包含唯一值计数(例如 265926639 等)。
data 数据框具有唯一值,但也有重复的条目实例(例如,265946567 的三个实例。此外,还有以下错误字符串漫画:421D6158-22D4-EDAC-0DEA-33B1FB5CC7AF
。
目标:
将 Lookup 和 data 分别合并到键列 ID_y
和 REFERENCE_ID
。
***参考资料和先前的搜索答案,但收效甚微:
-
Left merge without reindexing
Conditional Merge
Chris Albon's Tutorial
Merging multiple dataframes
Data Carpentry's Review
到目前为止我所做的尝试:
merged_left = pd.merge(left=Lookup,right=data, how='left', left_on='ID_y', right_on='REFERENCE_ID')
这将返回所有 Lookup 数据,但 data 数据框的所有 667 列都返回为 null价值观。
理论上,如果两个“key”列中有共同的数字,则来自 data 数据框的数据进行匹配。我的假设是要么存在数据类型冲突,要么因为 data 数据框中有重复的数字,因此没有发生合并。我想避免在 data 列中删除重复项或多个键实例,因为这可能包含有效数据。
我还尝试将ID_y
columnname 重命名为REFERENCE_ID
并执行如下合并:
Lookup=Lookup.rename(columns = 'ID_y':'REFERENCE_ID')
这会产生一个null
数据框(只有列,但没有值)。我还尝试将索引设置为ID_y
和REFERENCE_ID
,然后对索引执行合并:
Lookup = Lookup.set_index('ID_y')
data = data.set_index('REFERENCE_ID')
merged_on_index = pd.merge(Lookup,data, left_index=True,right_index=True)
我收到以下回溯:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-35-3909fd759082> in <module>()
----> 1 pd.merge(AgentLookup,data,left_index=True,right_index=True)
C:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\pandas\tools\merge.py in merge(left, right, how, on, left_on, right_on, left_index, right_index, sort, suffixes, copy)
36 right_index=right_index, sort=sort, suffixes=suffixes,
37 copy=copy)
---> 38 return op.get_result()
39 if __debug__:
40 merge.__doc__ = _merge_doc % '\nleft : DataFrame'
C:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\pandas\tools\merge.py in get_result(self)
184
185 def get_result(self):
--> 186 join_index, left_indexer, right_indexer = self._get_join_info()
187
188 ldata, rdata = self.left._data, self.right._data
C:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\pandas\tools\merge.py in _get_join_info(self)
257 if self.left_index and self.right_index:
258 join_index, left_indexer, right_indexer = \
--> 259 left_ax.join(right_ax, how=self.how, return_indexers=True)
260 elif self.right_index and self.how == 'left':
261 join_index, left_indexer, right_indexer = \
C:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\pandas\core\index.py in join(self, other, how, level, return_indexers)
2041 other = other.astype('O')
2042 return this.join(other, how=how,
-> 2043 return_indexers=return_indexers)
2044
2045 _validate_join_method(how)
C:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\pandas\core\index.py in join(self, other, how, level, return_indexers)
2054 else:
2055 return self._join_non_unique(other, how=how,
-> 2056 return_indexers=return_indexers)
2057 elif self.is_monotonic and other.is_monotonic:
2058 try:
C:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\pandas\core\index.py in _join_non_unique(self, other, how, return_indexers)
2125
2126 left_idx, right_idx = _get_join_indexers([self.values], [other.values],
-> 2127 how=how, sort=True)
2128
2129 left_idx = com._ensure_platform_int(left_idx)
C:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\pandas\tools\merge.py in _get_join_indexers(left_keys, right_keys, sort, how)
459
460 # get left & right join labels and num. of levels at each location
--> 461 llab, rlab, shape = map(list, zip( * map(fkeys, left_keys, right_keys)))
462
463 # get flat i8 keys from label lists
TypeError: type object argument after * must be a sequence, not map
此时,我不知道什么是最好的策略。我欢迎有关后续步骤的反馈。
【问题讨论】:
运行 merge_left 行时到底发生了什么?哪些列为空等 @AustinC “数据”数据框列的所有 667 列都包含空值。 【参考方案1】:您的两个连接字段都是不同的数据类型。 REFERENCE_ID
作为对象类型,ID_y
作为数字 int64
类型。有趣的是,pandas 中的 object
dtype 是一个 NumPy ndarray,它保存指向可变长度字符串项的指针。此外,object
是导入数据中同时包含字符串和数字时最通用的数据类型。
考虑使用astype 将连接字段转换为相同的数据类型。当然,字符串往往是最宽松的,允许使用连字符等各种字符。
字符串转换:
data['REFERENCE_ID'] = data['REFERENCE_ID'].apply(str) # NOTICE APPLY HERE
LookUp['ID_y'] = LookUp['ID_y'].astype(str)
数值转换:
data['REFERENCE_ID'] = data['REFERENCE_ID'].astype(int)
组合:
data['REFERENCE_ID'] = data['REFERENCE_ID'].astype(str).astype(int)
LookUp['ID_y'] = LookUp['ID_y'].astype(str).astype(int)
【讨论】:
对 str 的覆盖对两列都有效!谢谢!以上是关于Pandas Left Merge with xlsx with CSV 在输出中产生空值列的主要内容,如果未能解决你的问题,请参考以下文章