2016-06-23 20 views
0

即使数据帧中不存在该值,我也想获得每个值的频率的行计数。熊猫:根据列表中的值进行分组或过滤,而不是数据框

d = {'light' : pd.Series(['b','b','c','a','a','a','a'], index=[1,2,3,4,5,6,9]),'injury' : pd.Series([1,5,5,5,2,2,4], index=[1,2,3,4,5,6,9])} 

testdf = pd.DataFrame(d) 

    injury light 
1  1  b 
2  5  b 
3  5  c 
4  5  a 
5  2  a 
6  2  a 
9  4  a 

我想要得到'light'中每个唯一值的'伤害'每个唯一值的出现次数。

通常我只会用groupby(),或(在这种情况下,我想它是在一个特定的格式),pivot_table:

testdf.reset_index().pivot_table(index='light',columns='injury',fill_value=0,aggfunc='count') 

     index   
injury  1 2 4 5 
light     
a   0 2 1 1 
b   1 0 0 1 
c   0 0 0 1 

但在这种情况下,我竟要比较的记录数据框到外部值列表 - 在这种情况下,['a','b','c','d']。所以,如果“d”不存在此数据帧存在,那么我想它返回计数为零:

 index   
injury  1 2 4 5 
light     
a   0 2 1 1 
b   1 0 0 1 
c   0 0 0 1 
d   0 0 0 0 

我来根据每个值过滤数据帧,然后得到最接近该数据帧的大小:

for v in sorted(['a','b','c','d']): 
    idx2 = (df['light'].isin([v])) 
    df2 = df[idx2] 
    print(df2.shape[0]) 

4 
2 
1 
0 

但是,只返回来自'light'列的计数 - 而不是两列的交叉列表。

有没有办法使数据透视表或groupby()对象基于列表中的值对事物进行分组,而不是在数据框的列中进行分组?还是有更好的方法来做到这一点?

回答

0

试试这个:

df = pd.crosstab(df.light, df.injury,margins=True) 
df 

injury 1 2 4 5 All 
light     
a  0 2 1 1 4 
b  1 0 0 1 2 
c  0 0 0 1 1 
All 1 2 1 3 7 

df["All"] 

light 
a  4 
b  2 
c  1 
All 7 
+0

这是行不通的。我的问题是关于将数据框与现有值列表进行比较。如果'light'列中不存在'd',它应该包含一行零。你的不包括'd'。看到我上面的期望输出(倒数第二个代码部分)。 – ale19

相关问题