分配行的熊猫数组列表

Posted

技术标签:

【中文标题】分配行的熊猫数组列表【英文标题】:List of pandas arrays assigning rows 【发布时间】:2021-01-29 04:55:14 【问题描述】:

我有一个由 5 个熊猫数组组成的列表,每个数组大小为 4 x 3。 我想将它们的第三行更改为一行 0、一个、两个,无论列表中数组的索引是什么。 我编写了代码,一个 for 循环,当我打印结果时,它看起来正在工作:

A=pd.DataFrame(np.random.randn(4,3))
AList=5*[A]
AList[0].iloc[2,:]
for kkk0 in range(0,len(AList)):
    AList[kkk0].iloc[2,:]=kkk0*np.ones((1,3))
    print(AList[kkk0])
          0         1         2
0 -0.168639  0.300507  2.823529
1  0.608844  0.017578 -0.342164
2  0.000000  0.000000  0.000000
3  1.664176 -0.696303  0.239165
          0         1         2
0 -0.168639  0.300507  2.823529
1  0.608844  0.017578 -0.342164
2  1.000000  1.000000  1.000000
3  1.664176 -0.696303  0.239165
          0         1         2
0 -0.168639  0.300507  2.823529
1  0.608844  0.017578 -0.342164
2  2.000000  2.000000  2.000000
3  1.664176 -0.696303  0.239165
          0         1         2
0 -0.168639  0.300507  2.823529
1  0.608844  0.017578 -0.342164
2  3.000000  3.000000  3.000000
3  1.664176 -0.696303  0.239165
          0         1         2
0 -0.168639  0.300507  2.823529
1  0.608844  0.017578 -0.342164
2  4.000000  4.000000  4.000000
3  1.664176 -0.696303  0.239165

然而,荒谬的事情现在开始了: 当我在 for 循环结束后尝试查看 AList 的内容时,我发现 List 的所有组成 PAndas 数组的第三行都是 4 行!

AList
Out[3]: 
[          0         1         2
 0 -0.168639  0.300507  2.823529
 1  0.608844  0.017578 -0.342164
 2  4.000000  4.000000  4.000000
 3  1.664176 -0.696303  0.239165,
           0         1         2
 0 -0.168639  0.300507  2.823529
 1  0.608844  0.017578 -0.342164
 2  4.000000  4.000000  4.000000
 3  1.664176 -0.696303  0.239165,
           0         1         2
 0 -0.168639  0.300507  2.823529
 1  0.608844  0.017578 -0.342164
 2  4.000000  4.000000  4.000000
 3  1.664176 -0.696303  0.239165,
           0         1         2
 0 -0.168639  0.300507  2.823529
 1  0.608844  0.017578 -0.342164
 2  4.000000  4.000000  4.000000
 3  1.664176 -0.696303  0.239165,
           0         1         2
 0 -0.168639  0.300507  2.823529
 1  0.608844  0.017578 -0.342164
 2  4.000000  4.000000  4.000000
 3  1.664176 -0.696303  0.239165]

有什么想法吗?

【问题讨论】:

【参考方案1】:
A=pd.DataFrame(np.random.randn(4,3))
AList=5*[A]

# concat your list of frames
df = pd.concat(AList)
# use loc to assign values 
# use numpy's transpose with arange since you know the size of each padnas frame
df.loc[2, :] = np.transpose([np.arange(0,5)]*3)
# use numpy's split to split you frame back into a list of frames
AList_new = np.split(df, len(AList))

[          0         1         2
 0  1.687788 -0.770912 -0.027720
 1 -1.868220 -0.475117 -0.266580
 2  0.000000  0.000000  0.000000
 3 -0.537249  0.414133  1.623596,
           0         1         2
 0  1.687788 -0.770912 -0.027720
 1 -1.868220 -0.475117 -0.266580
 2  1.000000  1.000000  1.000000
 3 -0.537249  0.414133  1.623596,
           0         1         2
 0  1.687788 -0.770912 -0.027720
 1 -1.868220 -0.475117 -0.266580
 2  2.000000  2.000000  2.000000
 3 -0.537249  0.414133  1.623596,
           0         1         2
 0  1.687788 -0.770912 -0.027720
 1 -1.868220 -0.475117 -0.266580
 2  3.000000  3.000000  3.000000
 3 -0.537249  0.414133  1.623596,
           0         1         2
 0  1.687788 -0.770912 -0.027720
 1 -1.868220 -0.475117 -0.266580
 2  4.000000  4.000000  4.000000
 3 -0.537249  0.414133  1.623596]

【讨论】:

【参考方案2】:

这根本不是荒谬的。观察到行为的原因是,您创建了一个包含 5 次相同对象的列表。尽管您使用不同的索引来访问AList,但您始终访问的是同一个对象,因此如果您最后打印它,该对象将具有第 2 行中的最后一个值,即 4。 如果您执行@It_is_Chris 的逻辑,则 5 个对象会被连接起来,然后再次拆分。这是一种生成副本的漫长方式,您也可以这样做,只需对代码进行最小的更改:

import numpy as np

A=pd.DataFrame(np.random.randn(4,3))
# instead of creating a list with 5 identical 
# objects using 5 * [A], create 5 copies 
AList=[A.copy() for _ in range(5)]
AList[0].iloc[2,:]
for kkk0 in range(0,len(AList)):
    AList[kkk0].iloc[2,:]=kkk0*np.ones((1,3))
    print(AList[kkk0])
    
AList    

输出:

[          0         1         2
 0  0.319473 -0.503133 -0.394476
 1 -1.032836 -1.212072 -0.771076
 2  0.000000  0.000000  0.000000
 3  0.173137  0.387402 -1.256148,
           0         1         2
 0  0.319473 -0.503133 -0.394476
 1 -1.032836 -1.212072 -0.771076
 2  1.000000  1.000000  1.000000
 3  0.173137  0.387402 -1.256148,
           0         1         2
 0  0.319473 -0.503133 -0.394476
 1 -1.032836 -1.212072 -0.771076
 2  2.000000  2.000000  2.000000
 3  0.173137  0.387402 -1.256148,
           0         1         2
 0  0.319473 -0.503133 -0.394476
 1 -1.032836 -1.212072 -0.771076
 2  3.000000  3.000000  3.000000
 3  0.173137  0.387402 -1.256148,
           0         1         2
 0  0.319473 -0.503133 -0.394476
 1 -1.032836 -1.212072 -0.771076
 2  4.000000  4.000000  4.000000
 3  0.173137  0.387402 -1.256148]

【讨论】:

哇,好优雅的答案!谢谢@jottbe! 没问题,我很高兴它有帮助。

以上是关于分配行的熊猫数组列表的主要内容,如果未能解决你的问题,请参考以下文章

如何将整个列表分配给熊猫数据框的每一行

如何将列表中的值分配给熊猫数据框并控制每个列表元素在数据框中的分布/频率

来自另一个数据框的熊猫多索引分配

将列名分配给熊猫系列

将动态分配的数组读入列表

Numpy:将值分配给具有索引列表的二维数组