我有以下数据框:

    name        day       value     time
0   MAC000002   2012-12-16  0.147   09:30:00
1   MAC000002   2012-12-16  0.110   10:00:00
2   MAC000002   2012-12-16  0.736   10:30:00
3   MAC000003   2012-12-16  0.404   09:30:00
4   MAC000003   2012-12-16  0.845   10:00:00


我只想将值转换为numpy数组:

[[0.147, 0.110, 0.736],[0.404, 0.845 ...],...]


我能想到的唯一方法是旋转数据框,然后转储值:

new_df = pd.pivot_table(df,index=["name"],values=["value"])
data = new_df.values()


但是,数据集非常大,并且有成千上万的唯一名称,由于内存限制,我无法透视表。还有另一种方法来转储按名称保留天和时间顺序分组的值吗?

最佳答案

您可能走错了路:


pd.pivot_table不会在这里得到您想要的东西,默认情况下,它按组给出均值。当您想保留所有值时。
NumPy数组仅对固定尺寸具有很大的好处,例如每行的列数相同。在这里,似乎并非如此:一组可能有2个值,而另一个组有3个值。列表列表可能更合适。


我假设您已经按日期和时间对数据框进行了排序。然后一种解决方案是将GroupBy + applylist一起使用:

res = df.groupby('name', sort=False)['value'].apply(list).values.tolist()

print(res)

[[0.147, 0.11, 0.736], [0.40399999999999997, 0.845]]


通过将'name'转换为categorical,可能会看到一些性能改进。通过collections.defaultdict可以实现另一种解决方案,但这可能会更慢:

from collections import defaultdict

def group_apply(df):
    return df.groupby('name', sort=False)['value'].apply(list).values.tolist()

def group_dict(df):
    dd = defaultdict(list)
    for name, value in df[['name', 'value']].itertuples(index=False):
        dd[name].append(value)
    return list(dd.values())

df = pd.concat([df]*10000, ignore_index=True)

assert group_apply(df) == group_dict(df)

%timeit group_apply(df)  # 8.07 ms
%timeit group_dict(df)   # 39.1 ms

关于python - Pandas 列到numpy数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52803292/

10-12 16:39