如何将dicts元组列表转换为pandas数据帧

时间:2017-02-06 00:55:47

标签: pandas

问题陈述

我有一个dicts元组列表:[(A,B),(A,B),...]。我为字典写了AB,因为这些"类型"的键是相同的。

我想要一个数据框,其中包含来自A的一些键和来自B的一些键。

A中的某些键也出现在B中。我想保留A的密钥。

接近它的方法:

我可以想到几种方式,而且我很好奇哪种方式会更高效。我按照我对性能的最佳猜测顺序列出了它们:

  • 列表理解,构建新词典(或扩展A部分B),然后pd.DataFrame.from_records

  • pd.DataFrame.from_records有一个排除参数。首先合并较大的dicts,然后在构建数据帧时排除列。

  • 转置元组列表(可能是zip(*)?),创建两个数据框.from_records,每个A和B一个,从每个数据框中删除不必要的列,然后粘贴生成的数据帧并排在一起。

  • 使每个字典(行)成为一个数据帧,然后将它们垂直粘贴在彼此之上(appendconcat或其他东西)。

作为熊猫的完全新手,似乎很难分辨出每个操作是什么,以及何时构建视图或进行复制,所以我无法分辨出什么是昂贵的,什么是非#39;吨

  • 我错过了解决方法吗?

  • 我的解决方案的性能是否正确?

  • 如果不是字典,AB是数据框,那么连接它们会更快吗?数据帧有多少内存开销,并且通常的做法是拥有一行数据帧?

具体细节:

这是一些简化的示例数据,

[({"chrom": "chr1", "gStart": 1000, "gEnd": 2000, "other": "drop this"}, 
  {"chrom": "chr1": "pStart": 1500, "pEnd": 2500, "drop": "this"}), 
 ({"chrom": "chr2", "gStart": 8000, "gEnd": 8500, "other": "unimportant"}, 
  {"chrom": "chr2": "pStart": 7500, "pEnd": 9500, "drop": "me"}) ]

我认为结果将是以下结果:

 pd.DataFrame.from_records([ 
  {"chrom": "chr1", "gStart": 1000, "gEnd": 2000, "pStart": 1500, "pEnd": 2500}, 
  {"chrom": "chr2", "gStart": 8000, "gEnd": 8500, "pStart": 7500, "pEnd": 9500}  ] )

解决方案的伪代码我喜欢:

我认为如果字典有一个很好的就地select方法,这会有用:

A_fields = [...]
B_fields = [...]
A_B_merged = [a.select(A_fields).extend(b.select(B_fields)) for a, b in A_B_not_merged]

A_B_dataframe = pd.DataFrame.from_records(A_B_merged)

2 个答案:

答案 0 :(得分:1)

您需要降低输入的两个级别才能对其进行处理。那么你最好的朋友是chain.from_iterable

import itertools as it
pd.DataFrame.from_records(it.chain.from_iterable(l))
Out[21]: 
  chrom    gEnd  gStart    pEnd  pStart
0  chr1  2000.0  1000.0     NaN     NaN
1  chr1     NaN     NaN  2500.0  1500.0
2  chr2  8500.0  8000.0     NaN     NaN
3  chr2     NaN     NaN  9500.0  7500.0

这需要经典且易于清理:

pd.DataFrame.from_records(it.chain.from_iterable(l)).set_index('chrom').stack().unstack()
Out[22]: 
         gEnd  gStart    pEnd  pStart
chrom                                
chr1   2000.0  1000.0  2500.0  1500.0
chr2   8500.0  8000.0  9500.0  7500.0

答案 1 :(得分:0)

使用普通旧字典合并,通过pythonic(Python 3.5+)方式合并起始字典和结束字典,然后使用from_records构建DataFrame

pd.DataFrame.from_records([{**d[0],**d[1]} for d in k])

  chrom  gEnd  gStart  pEnd  pStart
0  chr1  2000    1000  2500    1500
1  chr2  8500    8000  9500    7500