系统地遍历 DF 的多列和多行以跨多列输出不同的列表大小

Posted

技术标签:

【中文标题】系统地遍历 DF 的多列和多行以跨多列输出不同的列表大小【英文标题】:Systematically iterate across multiple columns and rows of DF to output differing list sizes across multiple columns 【发布时间】:2018-07-01 17:19:36 【问题描述】:

我希望遍历此数据框以增加列['B'] 和列['C'] 的列表大小。这对这个例子并不重要,但这些列表将在每次迭代期间输入到一个函数中。 例如:

df = pd.DataFrame('A' : ['a','a','b','b'],
                   'B' : ['1','2','1','2'],
                   'C' : ['2','3','1','6'])

通过遍历这个dataframe,我希望得到如下的东西:

(以['B'] 列开头)

[1]
[1,2]
[1,2,1]
[1,2,1,2]

(然后是列['C']

[2]
[2,3]
[2,3,1]
[2,3,1,6]

这些列表将在每次迭代结束时放入一个函数中,但我遇到的问题是编写一个适当的 for 循环来对列表生成进行编码。

我的问题的第二个方面并不那么重要......但如果我也可以迭代地输出列表停止的['A'] 的值(例如,当遍历列['C'] 时) ,列表[2,3]['A'] = 'b' 相关,[2,3,1] 的列['C'] 中的列表与['A'] = 'b' 相关。

非常感谢任何帮助。

【问题讨论】:

【参考方案1】:
df['B'],df['C']=df[['B','C']].values[::None].T.cumsum(axis=1)
df.applymap(list)
Out[1118]: 
     A             B             C
0  [a]           [1]           [2]
1  [a]        [1, 2]        [2, 3]
2  [b]     [1, 2, 1]     [2, 3, 1]
3  [b]  [1, 2, 1, 2]  [2, 3, 1, 6]

更新

df[['B','C']]=df[['B','C']].applymap(list)
df
Out[1121]: 
   A             B             C
0  a           [1]           [2]
1  a        [1, 2]        [2, 3]
2  b     [1, 2, 1]     [2, 3, 1]
3  b  [1, 2, 1, 2]  [2, 3, 1, 6]

【讨论】:

不错的一个!虽然看起来 A 也被转换为列表列。【参考方案2】:

有点做作,但这可能是最简单的方法。请注意,在列表中添加非常昂贵。

df[['B', 'C']] = df[['B', 'C']].values.reshape(-1, 2, 1).tolist()
df[['B', 'C']].cumsum()

              B             C
0           [1]           [2]
1        [1, 2]        [2, 3]
2     [1, 2, 1]     [2, 3, 1]
3  [1, 2, 1, 2]  [2, 3, 1, 6]

诀窍是增加数组的维数,因此每个元素都变成一个包含单个元素的列表。分配回来后,您可以调用 df.cumsum,它按行操作并将列表累加在一起。

【讨论】:

从你的 cumsum 中找到另一种方式 :-)【参考方案3】:

另一种方法是使用“扩展窗口”功能:

>>> def expanding_window(obj):
        n = len(obj) + 1
        return [obj[:i] for i in range(1, n)]

>>> pd.DataFrame([expanding_window(df[k].tolist()) for k in df.columns], index=df.columns).T
              A             B             C
0           [a]           [1]           [2]
1        [a, a]        [1, 2]        [2, 3]
2     [a, a, b]     [1, 2, 1]     [2, 3, 1]
3  [a, a, b, b]  [1, 2, 1, 2]  [2, 3, 1, 6]

【讨论】:

【参考方案4】:

如果你想使用 for 循环,你可以这样做:

for col in ['B','C']:
    print([df[col].tolist()[:i+1] for i,v in enumerate(df[col].tolist())])

[['1'], ['1', '2'], ['1', '2', '1'], ['1', '2', '1', '2']]
[['2'], ['2', '3'], ['2', '3', '1'], ['2', '3', '1', '6']]

对于你的第二个问题,这是你所追求的吗?

for col in ['B','C']:
    print([df[col].tolist()[:i+1]+[df.A.iloc[i]] for i,v in enumerate(df[col].tolist())])

[['1', 'a'], ['1', '2', 'a'], ['1', '2', '1', 'b'], ['1', '2', '1', '2', 'b']]
[['2', 'a'], ['2', '3', 'a'], ['2', '3', '1', 'b'], ['2', '3', '1', '6', 'b']]

【讨论】:

以上是关于系统地遍历 DF 的多列和多行以跨多列输出不同的列表大小的主要内容,如果未能解决你的问题,请参考以下文章

当没有动态列时,将多列和多行的列连接成一个 varchar 值

循环遍历具有多列和多行的数组

多列上的列映射[重复]

多列上的多个聚合

在 R 中,如何真正快速地遍历数据帧的行?

excel怎么把1行转多列多行