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_yREFERENCE_ID(在 data 数据框中)。 Lookup 中的列包含唯一值计数(例如 265926639 等)。

data 数据框具有唯一值,但也有重复的条目实例(例如,265946567 的三个实例。此外,还有以下错误字符串漫画:421D6158-22D4-EDAC-0DEA-33B1FB5CC7AF

目标: 将 Lookupdata 分别合并到键列 ID_yREFERENCE_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_ycolumnname 重命名为REFERENCE_ID 并执行如下合并:

Lookup=Lookup.rename(columns = 'ID_y':'REFERENCE_ID')

这会产生一个null 数据框(只有列,但没有值)。我还尝试将索引设置为ID_yREFERENCE_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 在输出中产生空值列的主要内容,如果未能解决你的问题,请参考以下文章

Pandas的Merge实现

在 pandas.merge_asof 之后保留两个合并键

详解pandas库的pd.merge函数

详解pandas库的pd.merge函数

详解pandas库的pd.merge函数

python详解pandas库的pd.merge函数