как сгладить массив в панде dataframe - PullRequest
1 голос
/ 12 марта 2019

Предполагая, что у меня есть кадр данных pandas, такой как

df_p = pd.DataFrame(
   {'name_array':
    [[20130101, 320903902, 239032902],
     [20130101, 3253453, 239032902],
     [65756, 4342452, 32425432523]],
    'name': ['a', 'a', 'c']} )

Image of dataframe

Я хочу извлечь серию, которая содержит сплющенные массивы в каждой строке, пока сохранение порядка

Ожидаемый результат: pandas.core.series.Series

Image of expected output

Этот вопрос не является дубликатомпотому что мой ожидаемый вывод - это серия панд, а не датафрейм.

Ответы [ 3 ]

1 голос
/ 13 марта 2019

Решения, использующие melt, работают медленнее, чем оригинальный метод OP, которым они поделились в ответе здесь , особенно после ускорения моего комментария к этому ответу.

Я создал больший массив данных для тестирования:

df = pd.DataFrame({'name_array': np.random.rand(1000, 3).tolist()})

И синхронизация двух решений с использованием melt на этом фрейме данных дает:

In [16]: %timeit pd.melt(df.name_array.apply(pd.Series).reset_index(), id_vars=['index'],value_name='name_array').drop('variable', axis=1).sort_values('index')
173 ms ± 5.68 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [17]: %timeit df['name_array'].apply(lambda x: pd.Series([i for i in x])).melt().drop('variable', axis=1)['value']
175 ms ± 4.86 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Метод ОП с ускорением, который я предложил в комментариях:

In [18]: %timeit pd.Series(np.concatenate(df['name_array']))
18 ms ± 887 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

И, наконец, самое быстрое решение из представленных здесь , но измененное, чтобы обеспечить серию вместо вывода данных кадра:

In [14]: from itertools import chain
In [15]: %timeit pd.Series(list(chain.from_iterable(df['name_array'])))
402 µs ± 4.68 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Этот последний метод быстрее, чем melt() на 3 порядка, и быстрее, чем np.concatenate() на 2 порядка.

0 голосов
/ 13 марта 2019

Вы можете использовать pd.melt:

pd.melt(df_p.name_array.apply(pd.Series).reset_index(), 
        id_vars=['index'],
        value_name='name_array') \
        .drop('variable', axis=1) \
        .sort_values('index')

ВЫВОД:

index   name_array
0       20130101
0       320903902
0       239032902
1       20130101
1       3253453
1       239032902
2       65756
2       4342452
2       32425432523
0 голосов
/ 13 марта 2019

Это решение, которое я понял. Не знаю, есть ли более эффективные способы.

df_p = pd.DataFrame(
   {'name_array':
    [[20130101, 320903902, 239032902],
     [20130101, 3253453, 239032902],
     [65756, 4342452, 32425432523]],
    'name': ['a', 'a', 'c']} )

data = pd.DataFrame( {'column':np.concatenate(df_p['name_array'].values)} )['column']

выход:

[0       20130101
 1      320903902
 2      239032902
 3       20130101
 4        3253453
 5      239032902
 6          65756
 7        4342452
 8    32425432523
 Name: column, dtype: int64]
...