使用抛出ValueError的多列循环数据框
Posted
技术标签:
【中文标题】使用抛出ValueError的多列循环数据框【英文标题】:Looping over dataframe using multiple columns throwing ValueError 【发布时间】:2021-08-29 19:34:00 【问题描述】:我正在尝试在 Pandas 数据框中申请循环以一次访问两列。我的一段代码非常适合单列。但是当应用于多个列时,它会抛出:“ValueError : too many values to unpack (expected 2)”
我的代码sn-p如下-
for col1, col2 in df.columns:
if col1.startswith('ColumnName1') and col2.startswith('ColumnName2') and df[col2].notnull()*1:
new_df = df.groupby([col1, col2]).agg('ColumnName3': 'unique').reset_index()
elif col1.startswith('ColumnName1') and col2.startswith('ColumnName2') and not df[col2].notnull()*1:
new_df = df.groupby(col1).agg('ColumnName3': 'unique').reset_index()
小问题是列名太大并且不受控制,因为这个数据框有多头列,所以在合并后它们会创建一些随机填充名称。因此 “。以。。开始”。列名要大得多。
我正在尝试根据第 1 列和第 2 列执行第 3 列的分组,如果第 2 列不为空,否则当第 2 列为空时使用第 1 列进行分组。
谁能告诉我我哪里错了,或者我在这里错过了什么?
【问题讨论】:
好的,谢谢你的想法。所以我认为不可能像这样循环遍历数据框 如果您必须一次访问两列,不妨试试for col1, col2 in zip(df.columns, df.columns[1:]):
。这会迭代两个并行列表,其中一个是另一个的 1-shifted 版本,当较短的耗尽时它会停止。
【参考方案1】:
如果你想一次循环遍历df.columns
两个值,你可以这样做:
import itertools as it
for col1, col2 in it.zip_longest(*[iter(df.columns)]*2):
...
我们在列上创建一个包含迭代器的列表,然后应用*2
来获得一个包含两个相同迭代器对象的列表。因为它是同一个迭代器,所以每次我们迭代一个迭代器时,我们也会推进另一个迭代器。然后,我们将它们压缩在一起,从长度为 len(df.columns) // 2
的 2 项序列变为包含 2 项的 len(df.columns) // 2
元组的序列。
【讨论】:
这解决了错误。谢谢。很棒的概念洞察力,没想到会这样 这很有趣!这可以应用于选择不连续的列吗?例如,col1 与 col101,col2 与 col102,还是只重新排列列会更简单? @m_power 是的,您可以将df.columns
换成您想要的任何可迭代对象。确保可迭代的长度与您解压到的变量相匹配。您可以通过在参数列表中添加一个带有星号的变量来收集额外的值,如下所示:for a, b, *c in ...
。对于您建议的用例,您提供的可迭代对象必须订购 col1, col101, col2, col102, ...
。
@WillDaSilva,您认为这种方法是否比简单地在列范围上执行 for 循环更快(例如 for col in range(df.shape[1]):
并使用 df.iloc[:, col].somefunc(); df.iloc[:, col + 100].somefunc();
在循环内调用正确的列?跨度>
@WillDaSilva 我会对其进行基准测试并让您知道!我每次迭代使用超过两列,所以也许它实际上更具可读性!以上是关于使用抛出ValueError的多列循环数据框的主要内容,如果未能解决你的问题,请参考以下文章
如何为数据框中的多列循环 Bartlett 测试和 Kruskal 测试? [复制]