MultiIndex Dataframe 将一个原始索引与其他索引进行比较
MultiIndex Dataframe compare one index raw against others
我有一个以列表作为值的数据框。
index=pd.MultiIndex.from_product([["file1", "file2", "file3"], ["a", "b"]])
index.names = ['file', 'name']
data = [
[[1,1],[0,0]],
[[],[]],
[[2,2,2],[7]],
[[],[]],
[[1],[4, 4]],
[[],[]],
]
df = pd.DataFrame(data, index=index, columns=['col1', 'col2'])
df
df
col1 col2
file name
file1 a [1, 1] [0, 0]
b [] []
file2 a [2, 2, 2] [7]
b [] []
file3 a [1] [4, 4]
b [] []
我想按 name
和 运行 在每一行和其他行的串联之间进行 Kolmogorov-Smirnov 检验 (scipy.stats.ks_2samp
) 分组。名称示例 a
。 {file1,a}
== [1,1]
。其他的拼接{file2,a}
+ {file3,a}
== [2,2,2]
+ [1]
== [2,2,2,1]
。他们之间的KStest是stats.ks_2samp([1,1], [2,2,2,1])
== 0.75
。
我怎样才能得到下面的预期结果(手动完成)?
col1 col2
file name
file1 a 0.75 1.0
b NaN NaN
file2 a 1.0 1.0
b NaN NaN
file3 a 0.6 0.66
b NaN NaN
对不起,如果这个问题太临时了。
以下是我的尝试。我不知道如何从其他行中优雅地排除目标行。
df.groupby(['name']).apply(
lambda per_name_df: per_name_df.apply(
lambda per_column: per_column.apply(
lambda cell: stats.ks_2samp(cell, np.concatenate(per_column.to_numpy())) if cell else cell)))
... test between a single row and a concatenation of others rows
由于您没有具体指定哪些行,我会给您一个示例来测试第一行和所有剩余行:
from scipy.stats import ks_2samp
def ks(a, b):
b = [el for li in b for el in li]
if a and b:
return ks_2samp(a, b)[0]
df.groupby(df.index.get_level_values('name')).col1.apply(lambda x: ks(x[0],x[1:].to_list()))
结果:
name
a 0.75
b NaN
Name: col1, dtype: float64
已编辑问题的更新:
... test between each row and a concatenation of others rows
def ks_all(a):
a = a.to_list()
return [ks(a[i],a[:i]+a[i+1:]) for i in range(0,len(a))]
df.groupby(df.index.get_level_values('name')).transform(ks_all)
结果:
col1 col2
file name
file1 a 0.75 1.000000
b NaN NaN
file2 a 1.00 1.000000
b NaN NaN
file3 a 0.60 0.666667
b NaN NaN
我有一个以列表作为值的数据框。
index=pd.MultiIndex.from_product([["file1", "file2", "file3"], ["a", "b"]])
index.names = ['file', 'name']
data = [
[[1,1],[0,0]],
[[],[]],
[[2,2,2],[7]],
[[],[]],
[[1],[4, 4]],
[[],[]],
]
df = pd.DataFrame(data, index=index, columns=['col1', 'col2'])
df
df
col1 col2
file name
file1 a [1, 1] [0, 0]
b [] []
file2 a [2, 2, 2] [7]
b [] []
file3 a [1] [4, 4]
b [] []
我想按 name
和 运行 在每一行和其他行的串联之间进行 Kolmogorov-Smirnov 检验 (scipy.stats.ks_2samp
) 分组。名称示例 a
。 {file1,a}
== [1,1]
。其他的拼接{file2,a}
+ {file3,a}
== [2,2,2]
+ [1]
== [2,2,2,1]
。他们之间的KStest是stats.ks_2samp([1,1], [2,2,2,1])
== 0.75
。
我怎样才能得到下面的预期结果(手动完成)?
col1 col2
file name
file1 a 0.75 1.0
b NaN NaN
file2 a 1.0 1.0
b NaN NaN
file3 a 0.6 0.66
b NaN NaN
对不起,如果这个问题太临时了。
以下是我的尝试。我不知道如何从其他行中优雅地排除目标行。
df.groupby(['name']).apply(
lambda per_name_df: per_name_df.apply(
lambda per_column: per_column.apply(
lambda cell: stats.ks_2samp(cell, np.concatenate(per_column.to_numpy())) if cell else cell)))
... test between a single row and a concatenation of others rows
由于您没有具体指定哪些行,我会给您一个示例来测试第一行和所有剩余行:
from scipy.stats import ks_2samp
def ks(a, b):
b = [el for li in b for el in li]
if a and b:
return ks_2samp(a, b)[0]
df.groupby(df.index.get_level_values('name')).col1.apply(lambda x: ks(x[0],x[1:].to_list()))
结果:
name
a 0.75
b NaN
Name: col1, dtype: float64
已编辑问题的更新:
... test between each row and a concatenation of others rows
def ks_all(a):
a = a.to_list()
return [ks(a[i],a[:i]+a[i+1:]) for i in range(0,len(a))]
df.groupby(df.index.get_level_values('name')).transform(ks_all)
结果:
col1 col2
file name
file1 a 0.75 1.000000
b NaN NaN
file2 a 1.00 1.000000
b NaN NaN
file3 a 0.60 0.666667
b NaN NaN