pandas несовместимая форма для столбца сложного типа - PullRequest
2 голосов
/ 05 февраля 2020

Как добавить сложный тип (например, массив numpy) в качестве столбца к pandas фрейму данных?

df = pd.DataFrame({'foo':['bar', 'baz'], 'bar':[1,2]})
display(df)

my_array = np.array([[[0.61209572, 0.616934  , 0.94374808, 0.6818203 ],
        [0.4236548 , 0.64589411, 0.43758721, 0.891773  ]],

       [[0.52184832, 0.41466194, 0.26455561, 0.77423369],
        [0.5488135 , 0.71518937, 0.60276338, 0.54488318]]])

print(my_array)
print(df.shape)
print(my_array.shape)

df['complex_type'] = my_array

Сбой:

AssertionError: Shape of new values must be compatible with manager shape

My версия pandas: 1.0.0

edit

Более сложный пример:

#%%timeit
import numpy as np
import pandas as pd
from scipy.spatial import cKDTree

rng = np.random.RandomState(0)
n_points = 50
d_dimensions = 4
k_neighbours = 3

X = rng.random_sample((n_points, d_dimensions))

df = pd.DataFrame(X)
df = df.reset_index(drop=False)
df.columns = ['id_str', 'lat_1', 'long_1', 'lat_2', 'long_2']
df.id_str = df.id_str.astype(object)

tree = cKDTree(df[['lat_1', 'long_1', 'lat_2', 'long_2']])
dist,ind=tree.query(X, k=k_neighbours,n_jobs=-1)


df = df.join(pd.DataFrame({'complex_type' : [arr for arr in X[ind]]}))
#df['complex_type'] = list(X[ind])    
df.head()

Ответы [ 3 ]

2 голосов
/ 05 февраля 2020
In [29]: df = pd.DataFrame({'foo':['bar', 'baz'], 'bar':[1,2]}) 
    ...: display(df) 
    ...:  
    ...: my_array = np.array([[[0.61209572, 0.616934  , 0.94374808, 0.6818203 ], 
    ...:         [0.4236548 , 0.64589411, 0.43758721, 0.891773  ]], 
    ...:  
    ...:        [[0.52184832, 0.41466194, 0.26455561, 0.77423369], 
    ...:         [0.5488135 , 0.71518937, 0.60276338, 0.54488318]]]) 
    ...:                                                                                       
   foo  bar
0  bar    1
1  baz    2
In [30]: my_array.shape                                                                        
Out[30]: (2, 2, 4)

Назначение списка из двух (2,4) массивов работает:

In [31]: df['new'] = list(my_array)                                                            
In [32]: df                                                                                    
Out[32]: 
   foo  bar                                                new
0  bar    1  [[0.61209572, 0.616934, 0.94374808, 0.6818203]...
1  baz    2  [[0.52184832, 0.41466194, 0.26455561, 0.774233...

In [33]: df.info()                                                                             
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
foo    2 non-null object
bar    2 non-null int64
new    2 non-null object
dtypes: int64(1), object(2)
memory usage: 176.0+ bytes

Но учтите, что вы не получите (2,2,4) массив обратно от панд; Вы получаете массив (2,) с элементами массива.

In [34]: df['new'].to_numpy()                                                                  
Out[34]: 
array([array([[0.61209572, 0.616934  , 0.94374808, 0.6818203 ],
       [0.4236548 , 0.64589411, 0.43758721, 0.891773  ]]),
       array([[0.52184832, 0.41466194, 0.26455561, 0.77423369],
       [0.5488135 , 0.71518937, 0.60276338, 0.54488318]])], dtype=object)

Также будьте осторожны при сохранении такого кадра. Файл csv будет сложно перезагрузить.

1 голос
/ 05 февраля 2020

IIU C вам нужно сгладить массив, а затем просто присоединить его к вашему фрейму данных.

мы можем использовать ndarray.flatten & pd.join

new_df = pd.DataFrame(np.ndarray.flatten(my_array),columns=['complex_type']).join(df)

print(new_df)

 complex_type foo  bar
0   0.612096  bar  1.0
1   0.616934  baz  2.0
2   0.943748  NaN  NaN
3   0.681820  NaN  NaN
4   0.423655  NaN  NaN
5   0.645894  NaN  NaN
6   0.437587  NaN  NaN
7   0.891773  NaN  NaN
8   0.521848  NaN  NaN
9   0.414662  NaN  NaN
10  0.264556  NaN  NaN
11  0.774234  NaN  NaN
12  0.548813  NaN  NaN
13  0.715189  NaN  NaN
14  0.602763  NaN  NaN
15  0.544883  NaN  NaN

edit: update

если порядок такой же, то вы можете просто создать фрейм данных со списком comp и присоединить его к целевому фрейму данных по индексу.

new_df = df.join(pd.DataFrame({'complex_type' : [arr for arr in my_array]}))

print(new_df)

   foo  bar                                       complex_type
0  bar    1  [[0.61209572, 0.616934, 0.94374808, 0.6818203]...
1  baz    2  [[0.52184832, 0.41466194, 0.26455561, 0.774233...
0 голосов
/ 05 февраля 2020

для первого, создайте свой собственный массив массивов кортежей того, что когда-либо, и df примет это

a = [[12,12],[23,23]]
df["a"] = a

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

df = pd.DataFrame({'foo':['bar', 'baz'], 'bar':[1,2]})
df["c"] = [1,2,3]

возникнет та же ошибка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...