我有一个看起来像这样的数据框(第一行是索引号):
0 1 2 3 4 5 6 7 8
66 56 34 40 41 55 80 None None
90 91 12 44 89 60 11 45 60
10 20 49 90 33 40 67 55 None
.
.
我需要作为输出的是获取每个第三个值,忽略任何无值,然后将其重新堆叠到这样的单行中:
0 1 2
66 56 34
40 41 55
80 90 91
12 44 89
60 11 45
60 10 20
49 90 33
40 67 55
是否有一种简单的方法可以将其旋转和堆叠?
答案 0 :(得分:3)
首先,我们可以使用ravel
将所有值转换为平面数组,然后过滤掉None
和reshape
:
x = df.values.ravel()
x[x != None].reshape(-1,3) # pd.DataFrame(x[x != None].reshape(-1,3))
# if you want to have a DataFrame instead of
# numpy array
输出:
array([[66., 56., 34.],
[40., 41., 55.],
[80., 90., 91.],
[12., 44., 89.],
[60., 11., 45.],
[60., 10., 20.],
[49., 90., 33.],
[40., 67., 55.]])
答案 1 :(得分:2)
使用reshape
中的numpy
s=np.concatenate(df.values)
pd.DataFrame(s[s!='None'].reshape(-1,3))
Out[1345]:
0 1 2
0 66 56 34
1 40 41 55
2 80 90 91
3 12 44 89
4 60 11 45
5 60 10 20
6 49 90 33
7 40 67 55
答案 2 :(得分:0)
相当长的方法,但仍然可以使用。 1)将所有列转换为列表 2)删除NaN值 3)创建3个项目的列表,然后转换为dtaframe
import itertools
import math
lst = list(itertools.chain(*df.values))
lst = list(filter(lambda v: not math.isnan(v), lst))
df = pd.DataFrame([[lst[i], lst[i+1], lst[i+2]] for i in range(0,len(lst),3)])
df
答案 3 :(得分:0)
pd.DataFrame([*zip(*[iter(df.stack())] * 3)])
0 1 2
0 66.0 56.0 34.0
1 40.0 41.0 55.0
2 80.0 90.0 91.0
3 12.0 44.0 89.0
4 60.0 11.0 45.0
5 60.0 10.0 20.0
6 49.0 90.0 33.0
7 40.0 67.0 55.0
df.stack()
将2D df
变成1D
系列,同时删除空值[iter(df.stack())] * 3
在列表[]
中创建一个iter对象(可以并且将要用尽),然后将其乘以3。这将创建一个长度为3的列表,其中所有3个元素都指向同一个iter
对象。其结果是,当我在第一个位置中迭代该对象时,其余位置将耗尽该对象。zip
一起使用时,具有按3分组的作用。