Перегруппировка n-столбцов в 3 столбца Python - PullRequest
1 голос
/ 03 мая 2019

У меня есть кадр данных, который выглядит следующим образом (где первая строка - это порядковый номер ):

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
.
.

В качестве выходных данных мне нужно взять каждое 3-е значение, игнорировать любое Нет значений и заново собрать его в одну строку, например:

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

Есть ли простой способ развернуть и сложить его таким образом?

Ответы [ 4 ]

3 голосов
/ 03 мая 2019

Сначала мы можем преобразовать все значения в плоский массив с помощью ravel, а затем отфильтровать None s и 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.]])
2 голосов
/ 03 мая 2019

Использование 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
0 голосов
/ 04 мая 2019

Python Fairy Dust

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 при паденииnull
  • [iter(df.stack())] * 3 создает объект iter (который может и будет исчерпан) внутри списка [], затем умножает его на три.Это создает список длиной 3, в котором все 3 элемента указывают на один и тот же iter объект.Это приводит к тому, что когда я перебираю этот объект, находясь в первой позиции, он исчерпывает объект для остальных позиций.
  • Когда я zip эти 3 элемента вместе, это имеет эффект группировкина 3
  • Осталось перенести это в конструктор данных
0 голосов
/ 03 мая 2019

Довольно длинный метод, но все еще работает.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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...