我有一个文本文件(制表符分隔),我需要计算文本文件中每列的概率和熵。这是我的文本文件:
aaa 0.0520852296 0.1648703511 0.1648703511
bbb 0.1062639955 0.1632039268 0.1632039268
ccc 1.4112745088 4.3654577641 4.3654577641
ddd 0.4992644913 0.1648703511 0.1648703511
eeee 0.169058175 0.1632039268 0.1632039268
所以我可以使用以下代码计算概率:
import pandas as pd
f=open(mydata,'r')
df = pd.DataFrame(pd.read_csv(f, sep='\t', header=None, names=['val1', 'val2', 'val3']))
print(df)
df.loc[:,"val1":"val3"] = df.loc[:,"val1":"val3"].div(df.sum(axis=0), axis=1)
print(df)
输出,
aaa 0.0232736716 0.0328321936 0.0328321936
bbb 0.0474828153 0.0325003428 0.0325003428
ccc 0.6306113983 0.8693349271 0.8693349271
ddd 0.2230904597 0.0328321936 0.0328321936
eeee 0.0755416551 0.0325003428 0.0325003428
在那个输出上我想计算熵并给我结果作为输出文件,所以我有以下代码
import math
entropy = - sum([ p * math.log(p) / math.log(2.0) for p in df ])
但是我收到以下错误消息:
TypeError: a float is required
非常感谢任何帮助。 谢谢大家
答案 0 :(得分:5)
你的问题在于这一行
entropy = - sum([ p * math.log(p) / math.log(2.0) for p in df ])
如果您考虑(或打印出)p for p in df
给您的内容(例如,运行print([p for p in df])
),您会发现p
仅包含列的标题。因此,您要将文本标签传递到期望math
的{{1}}函数中。因此错误。
apply
可能适合您:
float
正如其他人所指出的那样,您可能希望通过将第0列作为索引来整理数据框 - 然后您不必使用
import math
def shannon(col):
entropy = - sum([ p * math.log(p) / math.log(2.0) for p in col])
return entropy
sh_df = df.loc[:,'val1':'val3'].apply(shannon,axis=0)
print(sh_df)
因此您可以使用以下方式导入数据:
df.loc[:,'val1':'val3']
并且避免使用繁琐的df = pd.read_csv(f, sep='\t', header=None, index_col=0, names=['val1', 'val2', 'val3'])
语法
答案 1 :(得分:1)
为什么不修复数据文件而不是尝试在python代码中执行此操作并降低可读性。它就像
一样简单sed 's/ \+/,/g' mydata > my_fixed_data
如果你使用linux,只需在命令行上运行它。它将用,
替换所有空格。
MYDATA
aaa 0.0520852296 0.1648703511 0.1648703511
bbb 0.1062639955 0.1632039268 0.1632039268
ccc 1.4112745088 4.3654577641 4.3654577641
ddd 0.4992644913 0.1648703511 0.1648703511
eeee 0.169058175 0.1632039268 0.1632039268
my_fixed_data
aaa,0.0520852296,0.1648703511,0.1648703511
bbb,0.1062639955,0.1632039268,0.1632039268
ccc,1.4112745088,4.3654577641,4.3654577641
ddd,0.4992644913,0.1648703511,0.1648703511
eeee,0.169058175,0.1632039268,0.1632039268
然后您可以简单地使用read_csv
功能,如
df = pd.read_csv('my_fixed_data', header=None, index_col=0, names=['val1', 'val2', 'val3'])
以下是数据框现在的样子:
val1 val2 val3
aaa 0.052085 0.164870 0.164870
bbb 0.106264 0.163204 0.163204
ccc 1.411275 4.365458 4.365458
ddd 0.499264 0.164870 0.164870
eeee 0.169058 0.163204 0.163204
我确信Windows也必须有等价物。只是谷歌吧。
您收到TypeError: a float is required
错误,因为for p in df
为您提供了列名而不是某些浮点值。您可能需要相应地修复它。
>>> for p in df:
... print p
...
val1
val2
val3
>>>
答案 2 :(得分:0)
尝试
entropy = - sum([ p * math.log(p) / math.log(2.0) for p in df.loc[:,"val1":"val3"] ])
PS:使用此功能将文件读入数据框:
df = pd.read_csv(f, sep='\t', header=None, names=['val1', 'val2', 'val3'])