我会创建一个新列,它是groupby的结果并应用另一列,同时保持数据帧的顺序(或者至少能够对其进行排序)。
例如: 我想按组
规范化信号列import dask
import numpy as np
import pandas as pd
from dask import dataframe
def normalize(x):
return ((x - x.mean())/x.std())
data = np.vstack([np.arange(2000), np.random.random(2000), np.round(np.linspace(0, 10, 2000))]).T
df = dataframe.from_array(data, columns=['index', 'signal', 'id_group'], chunksize=100)
df = df.set_index('index')
normalized_signal = df.groupby('id_group').signal.apply(normalize, meta=pd.Series(name='normalized_signal_by_group'))
normalized_signal.compute()
我确实得到了正确的系列,但索引被洗牌了。 我是否在数据框中重新阅读了这个系列文章?
我试过
df['normalized_signal'] = normalized_signal
df.compute()
但我得到
ValueError:并非所有分区都已知,无法对齐分区。请使用
set_index
设置索引。
我也尝试过合并,但是我的最终数据框最终被洗牌,没有简单的方法来沿着索引求助
df2 = df.merge(normalized_signal.to_frame(), left_index=True, right_index=True, how='left')
df2.compute()
当我计算系列时它比pandas中的sort_index()有效,但这看起来效率不高。
df3 = df.merge(normalized_signal.to_frame().compute().sort_index(), left_index=True, right_index=True, how='left')
df3.compute()
等效的熊猫方式是:
df4 = df.compute()
df4['normalized_signal_by_group'] = df4.groupby('id_group').signal.transform(normalize)
df4
答案 0 :(得分:2)
不幸的是,transform
尚未在dask中实现。我(丑陋)的解决方法是:
import numpy as np
import pandas as pd
import dask.dataframe as dd
pd.options.mode.chained_assignment = None
def normalize(x):
return ((x - x.mean())/x.std())
def dask_norm(gp):
gp["norm_signal"] = normalize(gp["signal"].values)
return(gp.as_matrix())
data = np.vstack([np.arange(2000), np.random.random(2000), np.round(np.linspace(0, 10, 2000))]).T
df = dd.from_array(data, columns=['index', 'signal', 'id_group'], chunksize=100)
df1 = df.groupby("id_group").apply(dask_norm, meta=pd.Series(name="a") )
df2 = df1.to_frame().compute()
df3 = pd.concat([pd.DataFrame(a) for a in df2.a.values])
df3.columns = ["index", "signal", "id_group", "normalized_signal_by_group"]
df3.sort_values("index", inplace=True)