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

时间:2015-07-24 18:41:59

标签: python vector pandas dataframe probability

我是Python Pandas的新手。

我有一个数据框" df"类似的东西:

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

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

  1. 完全分发,名称概率向量
  2. 为每个标记,名称概率向量
  3. 到目前为止我做了什么:

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

      df2 = df.groupby('name').sum()/df.shape[0]
      
    2. 对于每个标记,名称概率的向量:在此我直到现在才完成:

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

      但我无法将其标准化以计算与每个标记相对应的名称概率向量

    3. 此外,我不清楚如何从这两个数据框中获取所需的点积。

    4. 请帮我完成代码。

1 个答案:

答案 0 :(得分:2)

要获得分布/直方图,您可以在value_counts()对象上使用pd.Series,然后按.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