Pandas数据帧行的标准化

5

我需要规范化一个包含全部为零的数据框中的行。例如:

df= pd.DataFrame({"ID": ['1', '2', '3', '4'], "A": [1, 0, 10, 0], "B": [4, 0, 30, 0]})

ID  A   B
1   1   4
2   0   0
3   10  30
4   0   0 

我的方法是首先排除零值行,然后使用以下方法将非零子集归一化:
df1 = df[df.sum(axis=1) != 0]
df2 = df[df.sum(axis=1) == 0]
sum_row = df1.sum(axis=1)
df1.div(sum_row, axis=0)

然后将两个数据帧按以下方式连接起来:
pd.concat([df1, df2]).reset_index()

然而,当我应用 df1.div(sum_row, axis=0) 时,出现了以下错误:

ValueError: operands could not be broadcast together with shapes (6,) (2,)

请问如何解决这个错误,是否存在更加高效的方法。谢谢!

编辑:预期生成的数据框应该是这样的:

ID  A     B
1   0.2   0.8 
2   0     0
3   0.25  0.75
4   0     0 

1
请您添加期望的结果,谢谢。 - Anna Iliukovich-Strakovskaia
@AnnaIliukovich-Strakovskaia 完成了! - user3000538
3个回答

7

您可以在scikit-learn中使用Normalizer来进行数据预处理。

df= pd.DataFrame({"ID": ['1', '2', '3', '4'], "A": [1, 0, 10, 0], "B": [4, 0, 30, 0]})
df = df.set_index('ID')

from sklearn.preprocessing import Normalizer
df.iloc[:,:] = Normalizer(norm='l1').fit_transform(df)

print(df)

       A     B
ID            
1   0.20  0.80
2   0.00  0.00
3   0.25  0.75
4   0.00  0.00

这很棒,因为你可以轻松地更改所使用的规范。在我的情况下,我在SO上看到了很多l1规范的例子,而我需要根据当前需求对每一行进行l2归一化处理。 - demongolem

4
使用 div 函数:
df= pd.DataFrame({"ID": ['1', '2', '3', '4'], "A": [1, 0, 10, 0], "B": [4, 0, 30, 0]})
df.set_index("ID", inplace=True)
df.div(df.sum(axis=1), axis=0).fillna(0)

1
使用 meltcrosstab
newdf=df.melt('ID')
pd.crosstab(index=newdf.ID,columns=newdf.variable,values=newdf.value,normalize='index',aggfunc='mean')
Out[447]: 
variable     A     B
ID                  
1         0.20  0.80
2         0.00  0.00
3         0.25  0.75
4         0.00  0.00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接