Добавить массив numpy в качестве столбца во фрейм данных Pandas


85

У меня есть объект фрейма данных Pandas формы (X, Y), который выглядит так:

[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]

и многочисленная разреженная матрица (CSC) формы (X, Z), которая выглядит примерно так

[[0, 1, 0],
[0, 0, 1],
[1, 0, 0]]

Как я могу добавить содержимое из матрицы во фрейм данных в новом именованном столбце, чтобы фрейм данных выглядел следующим образом:

[[1, 2, 3, [0, 1, 0]],
[4, 5, 6, [0, 0, 1]],
[7, 8, 9, [1, 0, 0]]]

Обратите внимание, что фрейм данных теперь имеет форму (X, Y + 1), а строки из матрицы являются элементами в фрейме данных.


2
Такое гнездование не рекомендуется. Зачем тебе это нужно?
— Филлип Клауд


Я хочу сохранить возможность выбора предыдущего содержимого матрицы по одному имени столбца после слияния.
— Михай Дамиан

Почему бы тебе просто не использовать два DataFrameс?
— Филлип Клауд

Ответы:


81
import numpy as np
import pandas as pd
import scipy.sparse as sparse

df = pd.DataFrame(np.arange(1,10).reshape(3,3))
arr = sparse.coo_matrix(([1,1,1], ([0,1,2], [1,2,0])), shape=(3,3))
df['newcol'] = arr.toarray().tolist()
print(df)

дает

   0  1  2     newcol
0  1  2  3  [0, 1, 0]
1  4  5  6  [0, 0, 1]
2  7  8  9  [1, 0, 0]

6
Думаю, мы не можем предоставить пуленепробиваемую обувь для пользователей, которые настаивают на таких вещах: /
— Филлип Клауд

6
Есть интересные вещи, которые вы можете делать со столбцами списков , поэтому я бы не стал думать, что это обязательно плохая идея. Хотя я согласен, что высока вероятность, что это так.
— unutbu 05

1
Это прекрасный пример pandasгибкости. В случае этого вопроса данные уже имеют однородный числовой тип с строками одинаковой формы, тогда как в этом примере они имеют listразную длину. Я согласен с тем, что вы можете делать интересные вещи. Однако, если у вас уже есть матрица, зачем превращать ее в список списков?
— Филлип Клауд

1
Есть "интересная вещь" ... сделать его больше не столбцом списков (так что это полезно)!
— Энди Хайден

54
Мир становится лучше, когда творческим людям разрешают делать то, что все остальные считают глупостью. :)
— unutbu 05

10

Вместо хранения массива в столбце рассмотрите возможность использования структуры данных более высокого измерения ( панели ):

In [11]: p = pd.Panel({'df': df, 'csc': csc})

In [12]: p.df
Out[12]: 
   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9

In [13]: p.csc
Out[13]: 
   0  1  2
0  0  1  0
1  0  0  1
2  1  0  0

Посмотрите на сечения и т. Д. И т. Д. И т. Д.

In [14]: p.xs(0)
Out[14]: 
   csc  df
0    0   1
1    1   2
2    0   3

Подробнее о панелях см. В документации .


12
Панель теперь устарела
— гухур

Да, в настоящее время обычно рекомендуется MultiIndex. Создано, например, через pd.concat([df, csc], axis=1, keys=["df", "csc"]).
— Энди Хайден

A = np.eye(3); df = pd.concat( [A,A], axis=1 )-> TypeError: невозможно объединить объект, отличный от NDFrame в 20.2? (. Вики из «панд-Устаревшие-теперь потребительной этого» было бы неплохо)
— денис

@denis tryA = pd.DataFrame(np.eye(3)); df = pd.concat( [A,A], axis=1, keys=["A", "B"] )
— Энди Хайден

Спасибо, df.columns MultiIndex(levels=[[u'A', u'B'], [0, 1, 2]](хлопает по лбу)
— денис

3

Другой пример:

import numpy as np
import pandas as pd

""" This just creates a list of touples, and each element of the touple is an array"""
a = [ (np.random.randint(1,10,10), np.array([0,1,2,3,4,5,6,7,8,9]))  for i in 
range(0,10) ]

""" Panda DataFrame will allocate each of the arrays , contained as a touple 
element , as column"""
df = pd.DataFrame(data =a,columns=['random_num','sequential_num'])

В общем, секрет состоит в том, чтобы разместить данные в форме a = [(array_11, array_12, ..., array_1n), ..., (array_m1, array_m2, ..., array_mn)] и panda DataFrame упорядочит данные в n столбцах массивов. Конечно, вместо элементов можно использовать массивы массивов, в этом случае форма будет иметь вид: a = [[array_11, array_12, ..., array_1n], ..., [array_m1, array_m2, ..., array_mn ]]

Это результат, если вы напечатаете (df) из приведенного выше кода:

                       random_num                  sequential_num
0  [7, 9, 2, 2, 5, 3, 5, 3, 1, 4]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1  [8, 7, 9, 8, 1, 2, 2, 6, 6, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2  [3, 4, 1, 2, 2, 1, 4, 2, 6, 1]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3  [3, 1, 1, 1, 6, 2, 8, 6, 7, 9]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4  [4, 2, 8, 5, 4, 1, 2, 2, 3, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5  [3, 2, 7, 4, 1, 5, 1, 4, 6, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
6  [5, 7, 3, 9, 7, 8, 4, 1, 3, 1]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7  [7, 4, 7, 6, 2, 6, 3, 2, 5, 6]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8  [3, 1, 6, 3, 2, 1, 5, 2, 2, 9]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
9  [7, 2, 3, 9, 5, 5, 8, 6, 9, 8]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Другой вариант приведенного выше примера:

b = [ (i,"text",[14, 5,], np.array([0,1,2,3,4,5,6,7,8,9]))  for i in 
range(0,10) ]
df = pd.DataFrame(data=b,columns=['Number','Text','2Elemnt_array','10Element_array'])

Вывод df:

   Number  Text 2Elemnt_array                 10Element_array
0       0  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1       1  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2       2  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3       3  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4       4  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5       5  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
6       6  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7       7  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8       8  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
9       9  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Если вы хотите добавить другие столбцы массивов, то:

df['3Element_array']=[([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3])]

Окончательный вывод df будет:

   Number  Text 2Elemnt_array                 10Element_array 3Element_array
0       0  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
1       1  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
2       2  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
3       3  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
4       4  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
5       5  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
6       6  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
7       7  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
8       8  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
9       9  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]

1

Вы можете добавить и получить массив numpy из фрейма данных, используя это:

import numpy as np
import pandas as pd

df = pd.DataFrame({'b':range(10)}) # target dataframe
a = np.random.normal(size=(10,2)) # numpy array
df['a']=a.tolist() # save array
np.array(df['a'].tolist()) # retrieve array

Это основано на предыдущем ответе, который смутил меня из-за разреженной части, и это хорошо работает для нерезкого массива numpy.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.