我有一个dicts元组列表:[(A,B),(A,B),...]。我为字典写了A
和B
,因为这些"类型"的键是相同的。
我想要一个数据框,其中包含来自A
的一些键和来自B
的一些键。
A
中的某些键也出现在B
中。我想保留A
的密钥。
我可以想到几种方式,而且我很好奇哪种方式会更高效。我按照我对性能的最佳猜测顺序列出了它们:
列表理解,构建新词典(或扩展A
部分B
),然后pd.DataFrame.from_records
。
pd.DataFrame.from_records
有一个排除参数。首先合并较大的dicts,然后在构建数据帧时排除列。
转置元组列表(可能是zip(*)
?),创建两个数据框.from_records
,每个A和B一个,从每个数据框中删除不必要的列,然后粘贴生成的数据帧并排在一起。
使每个字典(行)成为一个数据帧,然后将它们垂直粘贴在彼此之上(append
或concat
或其他东西)。
作为熊猫的完全新手,似乎很难分辨出每个操作是什么,以及何时构建视图或进行复制,所以我无法分辨出什么是昂贵的,什么是非#39;吨
我错过了解决方法吗?
我的解决方案的性能是否正确?
如果不是字典,A
和B
是数据框,那么连接它们会更快吗?数据帧有多少内存开销,并且通常的做法是拥有一行数据帧?
这是一些简化的示例数据,
[({"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)
答案 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