2013-10-04 40 views
0

你好,我有一個數據框,我試圖通過索引來加減行。一個乾淨/高效的方式,通過在python熊貓中的索引來加總行

先在容易複製格式的數據:

data = [['Name1','Obj1','Ind1',10,5,3,6],['Name1','Obj1','Ind2',10,5,2,1],['Name1','Obj1','Ind3',10,5,5,2],['Name1','Obj2','Ind1',15,7,33,15],['Name1','Obj2','Ind2',15,7,15,9],['Name1','Obj2','Ind3',15,7,32,9]] 

然後數據幀:

>>> df = pd.DataFrame(data,columns=['Name','Object','Index','Const1','Const2','Method1','Method2']) 
>>> df 
    Name Object Index Const1 Const2 Method1 Method2 
0 Name1 Obj1 Ind1  10  5  3  6 
1 Name1 Obj1 Ind2  10  5  2  1 
2 Name1 Obj1 Ind3  10  5  5  2 
3 Name1 Obj2 Ind1  15  7  33  15 
4 Name1 Obj2 Ind2  15  7  15  9 
5 Name1 Obj2 Ind3  15  7  32  9 

這是一個截斷DF只有有一個「名稱」,但在現實DF可以有很多。儘管「指數」僅限於幾個值。在這種有限的情況下,我想通過「名稱」和「對象」分組來操作「方法」列,然後採取Ind1-Ind2-Ind3

我這樣做的原始的方式如下:

>>> for ind in ['Ind2','Ind3']: 
...  for meth in ['Method1','Method2']: 
...    df[meth][df['Index']==ind] *= -1 
... 
>>> df 
    Name Object Index Const1 Const2 Method1 Method2 
0 Name1 Obj1 Ind1  10  5  3  6 
1 Name1 Obj1 Ind2  10  5  -2  -1 
2 Name1 Obj1 Ind3  10  5  -5  -2 
3 Name1 Obj2 Ind1  15  7  33  15 
4 Name1 Obj2 Ind2  15  7  -15  -9 
5 Name1 Obj2 Ind3  15  7  -32  -9 

df['Const1'] /= 3 
df['Const2'] /= 3 

>>> df.groupby(['Name','Object']).sum() 
       Const1 Const2 Method1 Method2 
Name Object 
Name1 Obj1  10  5  -4  3 
     Obj2  15  7  -14  -3 

是否有使用Python熊貓這樣做的更好的辦法?

+0

你兩個'DataFrame's是不同的...你可以發佈你實際使用的那個嗎?你在'Const1'中有10和15,在'Const2'中有5和7,但是你提供的那個在這兩列中分別只有10和5。 –

+0

啊,是的,我已經糾正了數據。我試圖證明'Const'值是恆定的,不應該改變。這些值在每個組內都是一樣的。 – Daniel

+0

我的答案適用於您的任一數據集。 –

回答

2

假設你想給每個組內劃分Const1Const2它們的非空計數(以便總結時保留其價值更高版本):

In [20]: data = [['Name1','Obj1','Ind1',10,5,3,6], 
    ....:   ['Name1','Obj1','Ind2',10,5,2,1], 
    ....:   ['Name1','Obj1','Ind3',10,5,5,2], 
    ....:   ['Name1','Obj2','Ind1',10,5,33,15], 
    ....:   ['Name1','Obj2','Ind2',10,5,15,9], 
    ....:   ['Name1','Obj2','Ind3',10,5,32,9]] 

In [21]: df = DataFrame(data,columns=['Name','Object','Index','Const1','Const2','Method1','Method2']) 
In [22]: df 
Out[22]: 
    Name Object Index Const1 Const2 Method1 Method2 
0 Name1 Obj1 Ind1  10  5  3  6 
1 Name1 Obj1 Ind2  10  5  2  1 
2 Name1 Obj1 Ind3  10  5  5  2 
3 Name1 Obj2 Ind1  10  5  33  15 
4 Name1 Obj2 Ind2  10  5  15  9 
5 Name1 Obj2 Ind3  10  5  32  9 

In [23]: df.loc[df.Index.isin(['Ind2', 'Ind3']), ['Method1', 'Method2']] *= -1 

In [24]: def plyr(df): 
    ....:  df = df.copy() 
    ....:  df['Const1'] /= float(df.Const1.count()) 
    ....:  df['Const2'] /= float(df.Const2.count()) 
    ....:  return df 
    ....: 

In [25]: df.groupby(['Name', 'Object']).apply(lambda x: plyr(x)._get_numeric_data().sum()) 
Out[25]: 
       Const1 Const2 Method1 Method2 
Name Object 
Name1 Obj1  10  5  -4  3 
     Obj2  10  5  -14  -3 
+0

有趣的是,我希望有一個非常聰明的方式來做到這一點。我會再提問的時間多一點。 – Daniel

+0

它看起來像你想要劃分'Const1'和'Const2'的非空計數。我會編輯我的答案。 –

相關問題