我想对极坐标数据帧的每个数字列应用 Kruskal-Wallis 统计分析并返回一个新的数据帧,其中每列都保存 KW 的结果。
我的数据框由大量行和列组成,如下所示。
df = pl.from_repr("""
┌───────┬──────┬──────┐
│ Group ┆ col1 ┆ col2 │
│ --- ┆ --- ┆ --- │
│ str ┆ f64 ┆ f64 │
╞═══════╪══════╪══════╡
│ A ┆ 3.0 ┆ 4.0 │
│ B ┆ 3.2 ┆ 5.4 │
│ A ┆ null ┆ 3.2 │
│ A ┆ 1.0 ┆ 1.5 │
│ B ┆ 2.3 ┆ 2.3 │
└───────┴──────┴──────┘
""")
我想申请 KW 这样我就能得到这个:
团体 | col1 | col2 |
---|---|---|
[A,B] | {'Hstats':值1,'p_val':值2} | {'H_stats':值3,'p_val':值4} |
value** 是 kruskal-wallis 的结果。
我尝试了以下操作,我迭代每一列以获取输出。但它太乏味了,当数据帧大小太大时,计算时间可能会更长。
from scipy.stats import mstats
def kwa(arr):
try:
H,p = mstats.kruskalwallis(arr.to_list())
return {'Hstats': H, 'p_val':p}
except Exception:
return {'Hstats': 'NA', 'p_val':'NA'}
def calckwa(df):
dft = df.group_by('Group',maintain_order=True).all()
trendcols = dft.get_columns()[1:]
trendskwa = {**{trend.name : kwa(trend) for trend in trendcols}}
return trendskwa
kwa_dict = pl.from_dict(calckwa(df))
我也尝试遵循这个answer,它是用 Pandas 完成的,但是,当我尝试像下面这样使用 Polars 时,我收到了恐慌异常错误。
df_grp = df.group_by('Group')
df_new = df_grp.map_groups(lambda grp: grp.drop('Group').map_rows(kwa))
抛出错误:
PanicException: UDF failed: BindingsError: "Could not determine output type"
但是,如果我只是尝试使用任何由几个数字列组成并具有字符串“Group”的简单极坐标数据框,我也会收到此错误。
那么,任何人都可以帮助我如何将 kruskal-wallis 应用于极地数据帧的所有列,而不需要迭代它们,而无需将其转换为 pandas 数据帧(因为如果数据帧大小已经很大,则转换为 pandas 将需要更长)?
pl.reduce
:
from scipy.stats.mstats import kruskalwallis
df.select(pl.reduce(kruskalwallis, ('col1','col2')))
您可以按照您的预期在
groupby().agg
环境中进行操作
df.groupby("Group").agg(pl.reduce(kruskalwallis, ('col1','col2')))
要在自己的命名列中获取结果,您可以使用
to_struct
后跟 unnest
,如下所示...
(
df
.groupby("Group")
.agg(krusk=pl.reduce(kruskalwallis, ('col1','col2')))
.with_columns(pl.col('krusk').list.to_struct(fields=['Hstats','p_val']))
.unnest('krusk')
)
注意:在OP的问题中,有一个名为arr的参数。如果您使用的是旧版本的 Polars,那么上面的
.list
最近已经取代了 .arr
,但是,为此目的,它应该只是更改名称空间,而其他所有内容保持不变。