[英]How to use list comphrehension to find columns common to all Pandas dataframes
我需要找到所有 5 个不同 Pandas 数据帧中的所有列。 目前我正在使用这样的代码:
dfs = [df0, df1, df2, df3, df4]
cols = dfs[0].columns
for df in dfs[1:]:
cols &= df.columns
假设这段代码是正确的,我想知道是否可以在列表理解中执行此操作,如果没有,是否有更有效或更简洁的方式来获得相同的结果。
我们有 reduce 来处理这个可以与Index.intersection
一起使用的,很像 set.intersection:
from functools import reduce
reduce(pd.Index.intersection,[i.columns for i in dfs])
虚拟示例:
df1 = pd.DataFrame(columns=list('ABCDE'))
df2 = pd.DataFrame(columns=list('ABDE'))
from functools import reduce
dfs = [df1,df2]
reduce(pd.Index.intersection,[i.columns for i in dfs])
#Index(['A', 'B', 'D', 'E'], dtype='object')
If you really want to work with regular Python sets, you can pass in a lambda function that returns the intersection of two sets to the reduce
function:
from functools import reduce
dfs = [df0, df1, df2, df3, df4] # list of pandas DataFrames
columns_in_common = reduce( # a Python set
lambda s1, s2: s1.intersection(s2),
(set(df) for df in dfs)
)
虽然我同意pd.Index.Intersection
在处理 pandas 数据帧时更有意义。
编辑:
为了完整起见,这里有一种使用实际列表推导式的方法——尽管我们仅仅依靠其在单行中迭代序列的“副作用”而严重滥用了列表推导式。 我再说一遍:这不是构建列表推导的目的:它们应该只用于一件事且仅用于一件事,即构建一个列表。
result = []
_ = [
result.append(colname)
if (
colname not in result
and all(
colname in df.columns
for df in dfs
)
else None
for df in dfs
for colname in df.columns
]
在这里,列表_
(列表理解的结果)并不重要。 重要的是值是否已附加到result
列表中,具体取决于它们是否出现在所有 DataFrame 列中,以及它们是否不存在于result
列表本身中。
除了不必要的复杂之外,列表理解也比集合版本慢(可能是由于其中的三重 for 循环,也可能是由于 Python 列表中的搜索比 Python 集合慢)。 这是一个简单的测试用例:
套
>>> timeit.timeit("import functools;lists=[[1, 2, 3], [2, 3, 4, 5], [4, 5, 6, 6]];functools.reduce(lambda s1, s2: s1.intersection(s2), (set(s) for s in lists))")
1.8992446570046013
列表理解
>>> timeit.timeit("mylist=[];lists=[[1, 2, 3], [2, 3, 4, 5], [4, 5, 6, 6]];[mylist.append(e) if e not in mylist and all(e in sublist for sublist in lists) else None for slist in lists for e in slist]")
6.89644429100008
为什么我们不能简单地将 append 新列名添加到在列表理解中创建的同一列表的真正答案? 是因为我们没有对它的引用——无论如何,在列表理解本身完成之前。 我们需要该引用才能从列表推导式创建列表,其逻辑比简单的 if/else 语句更复杂。
tl;博士如果您的列表创建逻辑不是简单的 if/else 测试,那么您不能真正使用列表推导来现场创建新列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.