分配行的熊猫数组列表
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! 没问题,我很高兴它有帮助。以上是关于分配行的熊猫数组列表的主要内容,如果未能解决你的问题,请参考以下文章