如何在熊猫数据框中展平数组

Posted

技术标签:

【中文标题】如何在熊猫数据框中展平数组【英文标题】:how to flatten array in pandas dataframe 【发布时间】:2019-08-03 05:05:37 【问题描述】:

假设我有一个熊猫数据框,例如

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

我想提取包含每一行中扁平数组的系列,同时保留顺序

预期结果是pandas.core.series.Series

这个问题不是重复的,因为我的预期输出是熊猫系列,而不是数据框。

【问题讨论】:

那么name 列是无关紧要的? @AlexanderReynolds 是的,这无关紧要。只是数据框的一个示例 How to convert column with list of values into rows in Pandas DataFrame的可能重复 不是公认的答案,但第二个显示使用 chain.from_iterable 的答案应该适合你——你只需要将它传递给 Series 而不是 DataFrame 的构造函数.所以:pd.Series(list(chain.from_iterable(df['name_array']))) @AlexanderReynolds 我想出了一种可能的方法(我已将其作为答案发布)。我不知道这是否是一种有效的方法。 【参考方案1】:

使用 melt 的解决方案比 OP 的原始方法慢,他们在答案 here 中分享了这种方法,尤其是在我对该答案的评论加速之后。

我创建了一个更大的数据框进行测试:

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)

具有我在 cmets 中建议的加速的 OP 方法:

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)

最后,here 提供的最快解决方案,但经过修改以提供一系列而不是数据帧输出:

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 个数量级。

【讨论】:

【参考方案2】:

这是我想出的解决方案。不知道有没有更有效的方法。

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]

【讨论】:

您可以删除数据周围的[],因为您只是无缘无故地将新值放入列表中。此外,OP 要求提供一个系列,您正在创建一个数据框,然后使用列名对其进行索引以获得系列——您应该能够在没有中间人的情况下使用 Series() 构造函数本身:)。编辑:大声笑没有意识到你是 OP。 具体来说我是说你可以做到pd.Series(np.concatenate(df_p['name_array']))【参考方案3】:

你可以使用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

【讨论】:

【参考方案4】:

您可以展平列列表的列表,然后创建一系列列表,以这种方式:

pd.Series([element for row in df_p.name_array for element in row])

【讨论】:

以上是关于如何在熊猫数据框中展平数组的主要内容,如果未能解决你的问题,请参考以下文章

在熊猫数据框中展平嵌套的 Json

如何将包装为字符串的向量转换为熊猫数据框中的numpy数组?

如何展平熊猫数据框多列中的字典列表

如何有效地展平Spark数据框中的特征?

如何显示存储在熊猫数据框中的图像?

如何在熊猫数据框中插入列名? [复制]