Python 从列表列表中创建唯一值的频率表
我有如下列表:Python 从列表列表中创建唯一值的频率表,python,pandas,Python,Pandas,我有如下列表: def freq(list_): df = [] for c in list_: df_= pd.DataFrame.from_dict(Counter(c), orient = "index") df_.index.name = 'motif' df_.reset_index(inplace = True) df.append(df_) print(df_) print(df
def freq(list_):
df = []
for c in list_:
df_= pd.DataFrame.from_dict(Counter(c), orient = "index")
df_.index.name = 'motif'
df_.reset_index(inplace = True)
df.append(df_)
print(df_)
print(df)
df = reduce(lambda left,right: pd.merge(left,right,on=[0],
how='outer'), df).fillna('void')
df = df.T
df.columns = df.iloc[0]
df = df.iloc[1:]
df[df == "void"] = 0
col_names = sorted(df.columns)
df = df[col_names]
vals = df.values
sums = np.sum(vals, axis = 1)
freqs = vals / sums[:,None]
return pd.DataFrame(freqs).T
测试=['abc','bcd','dce'],['abc','ab','cd'],['cd',be']]
我想得到每个子列表的每个唯一值的频率。例如,第一个子列表
abc 1
bcd 1
dce 1
ab 0
ab 0
cd 0
为0
我正在尝试以下方法:
def freq(list_):
df = []
for c in list_:
df_= pd.DataFrame.from_dict(Counter(c), orient = "index")
df_.index.name = 'motif'
df_.reset_index(inplace = True)
df.append(df_)
print(df_)
print(df)
df = reduce(lambda left,right: pd.merge(left,right,on=[0],
how='outer'), df).fillna('void')
df = df.T
df.columns = df.iloc[0]
df = df.iloc[1:]
df[df == "void"] = 0
col_names = sorted(df.columns)
df = df[col_names]
vals = df.values
sums = np.sum(vals, axis = 1)
freqs = vals / sums[:,None]
return pd.DataFrame(freqs).T
但它不起作用
我想要的输出是一个数据帧,每个唯一的值作为一个列特征,每个子列表作为一行
如何做到这一点
编辑:
期望输出:
ab abc bcd be cd dce
0 0 .33 .33 0 0 .33
1 .33 .33 0 0 .33 0
2 0 0 0 .5 .5 0
由于您标记了熊猫,所以熊猫有一个解决方案
get\u dummies
pd.DataFrame(test).stack().str.get_dummies().sum(level=0)
Out[301]:
ab abc bcd be cd dce
0 0 1 1 0 0 1
1 1 1 0 0 1 0
2 0 0 0 1 1 0
更新
s=pd.DataFrame(test).stack().str.get_dummies().sum(level=0)
s.div(s.sum(1),0)
Out[312]:
ab abc bcd be cd dce
0 0.000000 0.333333 0.333333 0.0 0.000000 0.333333
1 0.333333 0.333333 0.000000 0.0 0.333333 0.000000
2 0.000000 0.000000 0.000000 0.5 0.500000 0.000000
与总和一起使用
:
df = pd.get_dummies(pd.DataFrame(test), prefix_sep='', prefix='').sum(level=0, axis=1)
print (df)
abc cd ab bcd be dce
0 1 0 0 1 0 1
1 1 1 1 0 0 0
2 0 1 0 0 1 0
或计数器
使用数据帧
构造函数,将NaN
s替换为0
并转换为整数
s:
from collections import Counter
df = pd.DataFrame([Counter(x) for x in test]).fillna(0).astype(int)
print (df)
ab abc bcd be cd dce
0 0 1 1 0 0 1
1 1 1 0 0 1 0
2 0 0 0 1 1 0
然后:
df = df.div(df.sum(axis=1), axis=0)
print (df)
ab abc bcd be cd dce
0 0.000000 0.333333 0.333333 0.0 0.000000 0.333333
1 0.333333 0.333333 0.000000 0.0 0.333333 0.000000
2 0.000000 0.000000 0.000000 0.5 0.500000 0.000000
我想这不是问题本身,但在我尝试的解决方案中,我将它从计数值更改为每行的频率。做这个改变最简单的方法是什么。谢谢你的帮助!我想这不是问题本身,但在我尝试的解决方案中,我将它从计数值更改为每行的频率。做这个改变最简单的方法是什么?我可以在不久的将来看到一个高效版本的使用,所以我会很感激的!嗯,那么
计数器
解决方案对性能应该更好。@JackArnestad-可以用真实数据检查性能吗?我刚刚意识到生成虚拟数据并不容易。