使用抛出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 测试? [复制]

Python:如何从具有多列的数据框中循环遍历每两列组合以进行聚类?

通过比较 pyspark 数据框中的多列来更新一列

连接数据框会创建太多列

ValueError:不能将现有列的名称用于指示符列