У меня есть следующий фреймворк:
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
не даст вам то, что вы хотите здесь, по умолчанию оно дает среднее значение по группе. Хотя вы хотите сохранить все значения. Предположим, вы уже отсортировали свой файл данных по дате и времени. Тогда одно решение - использовать GroupBy
+ apply
со list
:
res = df.groupby('name', sort=False)['value'].apply(list).values.tolist()
print(res)
[[0.147, 0.11, 0.736], [0.40399999999999997, 0.845]]
Вы можете увидеть некоторое улучшение производительности путем преобразования 'name'
в категориальный. Другое решение возможно через 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