मेरे पास नीचे की तरह एक डेटाफ्रेम है

Class|  Student|    V1| V2| V3| wb

A|      Max|        10| 12| 14| 1

A|      Ann|        9|  6|  7|  0.9

B|      Tom|        6|  7|  10| 0.3

B|      Dick|       3|  8|  7|  0.7

C|      Dibs|       5|  2|  3|  0.8

C|      Mock|       6|  4|  3|  0.6

D|      Sunny|      3|  4|  5|  0.9

D|      Lock|       8|  3|  6|  1

और मैं कक्षा द्वारा समूहीकृत वी 1, वी 2, वी 3 के लिए भारित माध्य की गणना करना चाहता हूं, परिणाम नीचे जैसा कुछ होना चाहिए

Class  V1_M  V2_M V3_M

A   9  8   3

B   5  3   3

C   4  4   3

अब तक मैं प्रत्येक कॉलम के लिए डेटा फ्रेम अलग कर सकता हूं। लेकिन मैं बहुत अक्षम महसूस करता हूँ

और यहाँ 1 वेरिएबल के लिए कोड है

import pandas as pd
import numpy as np

def wtdavg(frame, var, wb):
  d = frame[var]
  w = frame[wb]
  return (d * w).sum() / w.sum()

df = pd.read_csv('Sample.csv')
Matrix = df.groupby(['Class']).apply(wtdavg,var='V2',wb='wb')
print(Matrix)

मैं 1 सप्ताह के पांडा अनुभव के साथ नौसिखिया हूं। अग्रिम में धन्यवाद।

मैक्स

1
mAx 13 मई 2017, 07:00

3 जवाब

सबसे बढ़िया उत्तर
#use apply to calculate weighted mean for alll 3 columns in one go.
df2 = df.groupby('Class').apply(lambda x: pd.Series([sum(x.V1*x.wb)/sum(x.wb), sum(x.V2*x.wb)/sum(x.wb), sum(x.V3*x.wb)/sum(x.wb)]))
#rename columns
df2.columns=['V1_M','V2_M','V3_M']

df2
Out[858]: 
           V1_M      V2_M       V3_M
Class                               
A      9.526316  9.157895  10.684211
B      3.900000  7.700000   7.900000
C      5.428571  2.857143   3.000000
D      5.631579  3.473684   5.526316

अपडेट करें (मान कॉलम की गतिशील सूची, यानी var_cols)

#put all your variable names in a list (can be copied over from df.columns)
var_cols = ['V1', 'V2', 'V3']
df2 = df.groupby('Class').apply(lambda x: pd.Series([sum(x[v] * x.wb) / sum(x.wb) for v in var_cols]))
df2.columns = [e+'_M' for e in var_cols]
           V1_M      V2_M       V3_M
Class                               
A      9.526316  9.157895  10.684211
B      3.900000  7.700000   7.900000
C      5.428571  2.857143   3.000000
D      5.631579  3.473684   5.526316
3
Zz'Rot 30 अगस्त 2019, 08:27
बहुत - बहुत धन्यवाद। क्या होगा यदि मेरे पास चर के 100s हैं। क्या हमारे पास लैम्ब्डा x के लिए गतिशील श्रृंखला हो सकती है: pd.Series([sum(x.V1*x.wb)/sum(x.wb) ....... v1000 तक)
 – 
mAx
13 मई 2017, 08:20
बहुत बहुत धन्यवाद... इसने पूरी तरह से काम किया
df2 = df.groupby('Class').apply(lambda x: pd.Series([sum(x[v]*x.wb)/sum(x. wb) v के लिए var_cols में]))
 – 
mAx
13 मई 2017, 12:14

अधिक सामान्य समाधान:

1.यह Student, Class के बिना सभी स्तंभों के लिए भारित माध्य बनाता है:

df2 = df.drop('Student', axis=1) \
        .groupby('Class') \
        .apply(lambda x: x.drop(['Class', 'wb'], axis=1).mul(x.wb, 0).sum() / (x.wb).sum()) \
        .add_suffix('_M') \
        .reset_index()
print (df2)
  Class      V1_M      V2_M       V3_M
0     A  9.526316  9.157895  10.684211
1     B  3.900000  7.700000   7.900000
2     C  5.428571  2.857143   3.000000
3     D  5.631579  3.473684   5.526316

या आप भारित माध्य के लिए कॉलम परिभाषित कर सकते हैं:

df2 = df.groupby('Class') \
        .apply(lambda x: x[['V1', 'V2', 'V3']].mul(x.wb, 0).sum() / (x.wb).sum()) \
        .add_suffix('_M') \
        .reset_index()
print (df2)
  Class      V1_M      V2_M       V3_M
0     A  9.526316  9.157895  10.684211
1     B  3.900000  7.700000   7.900000
2     C  5.428571  2.857143   3.000000
3     D  5.631579  3.473684   5.526316

अधिक सामान्य है फ़िल्टर सभी कॉलम V से filter:

df2 = df.groupby('Class') \
        .apply(lambda x: x.filter(regex='^V').mul(x.wb, 0).sum() / (x.wb).sum()) \
        .add_suffix('_M') \
        .reset_index()
print (df2)
  Class      V1_M      V2_M       V3_M
0     A  9.526316  9.157895  10.684211
1     B  3.900000  7.700000   7.900000
2     C  5.428571  2.857143   3.000000
3     D  5.631579  3.473684   5.526316
1
jezrael 13 मई 2017, 11:51
import pandas as pd
import numpy as np

def wtdavg(frame, var, wb):
  d = frame[var]
  w = frame[wb]
  return (d * w).sum() / w.sum()

df = pd.read_csv('Sample.csv')
temp_df = pd.DataFrame()
for column in df.columns:
    if df[column].dtype == np.int64:
        temp_S = pd.DataFrame( df[column].groupby(df['Class']).mean())
        frames = [temp_df, temp_S]
        temp_df = pd.concat(frames, axis = 'columns')
print temp_df
0
Amey Yadav 13 मई 2017, 07:18
मैंने माध्य के बजाय wtdavg लागू करने का प्रयास किया, लेकिन मान गलत हैं। उसके लिए एक नमूना है?
 – 
mAx
13 मई 2017, 08:21