我有一个列数可变的 DataFrame。我需要计算所选列的每个唯一值与其他列的每个唯一组合的比例。例如:
import numpy as np
import pandas as pd
a="A";b="B"
df = pd.DataFrame({
"n": [a,a,a,b,a,b,b,b],
"X": [0,0,0,0,1,1,1,1],
"Y": [0,0,1,1,0,0,0,0],
})
print(df)
n X Y
0 A 0 0
1 A 0 0
2 A 0 1
3 B 0 1
4 A 1 0
5 B 1 0
6 B 1 0
7 B 1 0
假设我们要计算
n
和 n_ru
(绝对频率 X
)的每个唯一组合的唯一 Y
(绝对频率 n_u
)的比例。
例如,4个n=B
的组合得到3个(X=1,Y=0)
,因此比例为3/4
,依此类推
我想这样做
# complete column list
col = list(df.columns.values)
# column list except n
cov = list(df.columns[1:].values)
# merge absolute frequencies
count = pd.merge(
# absolute freq of each (X,Y)
df.groupby(cov).count(),
# absolute freq of n for each (X,Y)
df.groupby(col).aggregate("n").count(),
# options
on=cov, suffixes=["_u", "_ru"]
)
print(count)
# calculate ell metric
ell = np.sum(
np.log(count["n_ru"]/count["n_u"])
)
print(f"ell = {ell:.3f}")
n_ru n_u
X Y
0 0 2 2
1 1 2
1 1 2
1 0 1 4
0 3 4
ell = -3.060
有更好的方法吗?
DataFrame.value_counts
,将系列除以Series.div
,并在列表cov
中指定计数列,因此此处不需要merge
:
ell = np.sum(np.log(df.value_counts().div(df[cov].value_counts())))
print(f"ell = {ell:.3f}")
ell = -3.060
如果需要先
count
输出:
count = (df.value_counts()
.to_frame('n_ru')
.droplevel(0)
.assign(n_u=lambda x: df[cov].value_counts()))
print (count)
n_ru n_u
X Y
1 0 3 4
0 0 2 2
1 1 2
1 0 1 4
0 1 1 2