从 Python pandas 数据帧生成概率向量并计算两个这样的向量的点积

Generate probability vectors from Python pandas dataframe and calculate dot product of two such vectors

我是 Python Pandas 的新手。

我有一个数据框 "df" 类似于:

    marks   name
0   70      Harish
1   40      Neha
2   70      Swati
3   90      Neha
4   60      Ram

现在我想要以下两个向量的点积:

  1. 完全分布,名称概率向量
  2. 对于每个标记,名称概率向量

到目前为止我做了什么:

  1. 完全分布,名称概率向量:

    df2 = df.groupby('name').sum()/df.shape[0]
    
  2. for each marks, vector of name probability: 到目前为止我只做了以下操作:

    df3 = df.groupby(['marks', 'name'], as_index=False).sum()
    

    但我无法将其归一化以计算对应于每个标记的名称概率向量

  3. 另外我不是很清楚如何从这两个数据帧中获取所需的点积。

请帮我完成代码。

要得到distribution/histogram,可以在pd.Series对象上使用value_counts(),然后用.sum()归一化计算百分比。

import pandas as pd
import numpy as np

# simulate some artificial data
# ==================================
np.random.seed(0)
df = pd.DataFrame({'marks': np.random.randint(5,10, 100)*10, 'name': np.random.choice(list('ABCDEFG'), 100)})

df

    marks name
0      90    C
1      50    D
2      80    C
3      80    B
4      80    C
5      60    G
6      80    D
7      70    G
8      90    D
9      50    D
..    ...  ...
90     50    A
91     80    A
92     70    E
93     70    D
94     50    D
95     60    B
96     50    G
97     70    F
98     70    F
99     80    A

[100 rows x 2 columns]

# Q1. full dist
# ==========================
temp = df['name'].value_counts()
temp

D    21
A    20
G    15
C    13
F    13
B     9
E     9
dtype: int64

# normalize    
temp/temp.sum()

D    0.21
A    0.20
G    0.15
C    0.13
F    0.13
B    0.09
E    0.09
dtype: float64

# Q2. groupby on marks
# =========================
def func(s):
    temp = s.value_counts()
    return temp/temp.sum()

res = df.groupby('marks')['name'].apply(func)
res

marks   
50     G    0.3182
       D    0.2273
       A    0.1818
       B    0.0909
       F    0.0909
       E    0.0455
       C    0.0455
60     C    0.2500
       B    0.1500
       D    0.1500
             ...  
80     D    0.1364
       C    0.1364
       G    0.0455
       F    0.0455
90     D    0.2632
       F    0.2105
       G    0.1579
       C    0.1579
       A    0.1579
       E    0.0526
dtype: float64

更新:

import pandas as pd
import numpy as np

# simulate some artificial data
# ==================================
np.random.seed(0)
df = pd.DataFrame({'marks': np.random.randint(5,10, 1000)*10, 'name': np.random.choice(list('ABCDEFG'), 1000)})

# full dist
# ==================================
temp = df['name'].value_counts()
full_dist = (temp/temp.sum()).sort_index()
full_dist

A    0.146
B    0.140
C    0.143
D    0.161
E    0.138
F    0.145
G    0.127
dtype: float64

# dist for each marks
# ===============================
def func(s):
    temp = s.value_counts()
    return temp/temp.sum()

res = df.groupby('marks')['name'].apply(func)
# reshape the result to unstacked table
table_marks = res.unstack(level='marks')
table_marks

marks      50      60      70      80      90
A      0.1206  0.1421  0.1615  0.1448  0.1623
B      0.1206  0.1371  0.1198  0.1584  0.1623
C      0.1809  0.1472  0.1198  0.1674  0.0942
D      0.1809  0.1675  0.1562  0.1538  0.1466
E      0.1357  0.1574  0.1302  0.1041  0.1675
F      0.1357  0.1472  0.1406  0.1538  0.1466
G      0.1256  0.1015  0.1719  0.1176  0.1204

# calculate dot product for each marks
# ========================================
table_marks.apply(lambda col: col*full_dist).sum()

marks
50    0.1438
60    0.1439
70    0.1428
80    0.1436
90    0.1432
dtype: float64