根据另一列中的值对pandas数据框中的列进行归一化 - python

我想根据另一列中的值对熊猫数据框的一列中的值进行标准化。从统计意义上讲,这不是纯粹的归一化。第二个值是一个类型;我想对每种类型的所有第一个值求和,然后在每一行中,将该值除以该行类型的总数。一个例子应该使这一点更清楚。

df = pd.read_table(datafile, names = ["A", "B", "value", "type"])

    A   B  value   type
0  A1  B1      1  type1
1  A2  B2      1  type1
2  A1  B1      1  type2
3  A1  B3      1  type3
4  A2  B2      1  type2
5  A2  B4      1  type3
6  A3  B4      1  type2
7  A3  B5      1  type3
8  A4  B6      1  type2
9  A4  B7      1  type3

然后我可以找到类似的总和:

types = df.groupby(["type"])["value"].sum()

type
type1    2
type2    4
type3    4
Name: value, dtype: int64

那我怎么用它来规范每一行的值呢?

我可以使用这样的循环来计算标准化值:

norms = []
for ix, row in df.iterrows():
    norms.append(row["value"]/types[row["type"]])

然后用具有以下值的新列替换该列:

df["value"] = pd.Series(norms)

    A   B  value   type
0  A1  B1   0.50  type1
1  A2  B2   0.50  type1
2  A1  B1   0.25  type2
3  A1  B3   0.25  type3
4  A2  B2   0.25  type2
5  A2  B4   0.25  type3
6  A3  B4   0.25  type2
7  A3  B5   0.25  type3
8  A4  B6   0.25  type2
9  A4  B7   0.25  type3

但是据我了解,使用这样的循环不是非常有效或适当,并且可能有一种使用某些标准pandas函数的方法。

谢谢。

python大神给出的解决方案

您可以使用transform,它对每个组执行一个操作,然后将结果扩展回原来的索引。例如”

>>> df["value"] /= df.groupby("type")["value"].transform(sum)
>>> df
    A   B  value   type
0  A1  B1   0.50  type1
1  A2  B2   0.50  type1
2  A1  B1   0.25  type2
3  A1  B3   0.25  type3
4  A2  B2   0.25  type2
5  A2  B4   0.25  type3
6  A3  B4   0.25  type2
7  A3  B5   0.25  type3
8  A4  B6   0.25  type2
9  A4  B7   0.25  type3

因为我们有

>>> df.groupby("type")["value"].transform(sum)
0    2
1    2
2    4
3    4
4    4
5    4
6    4
7    4
8    4
9    4
dtype: int64