2016-09-23 4 views
0

Этот DataFrame имеет два столбца, оба типа объекта.pandas pivot table aggfunc troubleshooting

Dependents Married 
0   0  No 
1   1  Yes 
2   0  Yes 
3   0  Yes 
4   0  No 

Я хочу объединить «зависимых» на основе «Женат».

table = df.pivot_table(
     values='Dependents', 
     index='Married', 
     aggfunc = lambda x: x.map({'0':0,'1':1,'2':2,'3':3}).mean()) 

Это работает, однако, на удивление, следующий не будет:

table = df.pivot_table(values = 'Dependents', 
     index = 'Married', 
     aggfunc = lambda x: x.map(int).mean()) 

Он будет производить None вместо этого.

Может ли кто-нибудь помочь объяснить?

+0

Смотрит вы пропустили набор скобок вокруг лямбды во втором сете. Кроме того, почему бы просто не использовать aggfunc = int? –

+0

Есть ли причина, по которой вы не конвертируете все это в целые числа при импорте или предварительной обработке? 'df = pd.read_csv ('bleh.csv'). assign (Dependents = lambda d: d.Dependents.astype (" int "))' или аналогичный метод? –

+0

@Sohier Dane. Я не верю, что() пропущено вокруг лямбда-функции. Я пытался сопоставить pd-серию, если str для int затем получает среднее значение. Мне нужно знать, что средние иждивенцы, у которых есть женатые, имеют сингл. – FrankZhu

ответ

0

Оба примера кода, предоставленные в вашем вопросе. Однако они не являются идиоматическим способом достижения того, что вы хотите сделать, особенно первого.

Я думаю, что это правильный способ получить ожидаемое поведение.

# Test data 
df = DataFrame({'Dependents': ['0', '1', '0', '0', '0'], 
       'Married': ['No', 'Yes', 'Yes', 'Yes', 'No']}) 

# Converting object to int 
df['Dependents'] = df['Dependents'].astype(int) 
# Computing the mean by group 
df.groupby('Married').mean() 

     Dependents 
Married    
No    0.00 
Yes   0.33 

Однако, следующий код работает.

df.pivot_table(values = 'Dependents', index = 'Married', 
       aggfunc = lambda x: x.map(int).mean()) 

Это эквивалентно (и более удобным для чтения) преобразования в int с map, прежде чем данные поворота.

df['Dependents'] = df['Dependents'].map(int) 
df.pivot_table(values = 'Dependents', index = 'Married') 

Редактировать

Я у вас есть грязный DataFrame, вы можете использовать to_numeric с параметром error, установленным в coerce.

Если coerce, то недействителен разбор будет установлен в качестве NaN

# Test data 
df = DataFrame({'Dependents': ['0', '1', '2', '3+', 'NaN'], 
       'Married': ['No', 'Yes', 'Yes', 'Yes', 'No']}) 

df['Dependents'] = pd.to_numeric(df['Dependents'], errors='coerce') 
print(df) 

    Dependents Married 
0   0.0  No 
1   1.0  Yes 
2   2.0  Yes 
3   NaN  Yes 
4   NaN  No 

print(df.groupby('Married').mean()) 

     Dependents 
Married    
No    0.0 
Yes    1.5 
+0

есть. Я согласен, что он чище. но я не знаю, почему это не работает.может быть, есть и другая причина. я в порядке, чтобы закрыть эту проблему – FrankZhu

+0

Отлично, поэтому вы можете проверить ответ – Romain

+0

Я хочу указать, что когда данные не чисты, ваш подход может быть затруднен, с 'df = DataFrame ({'Dependents': ['0 ',' 1 ',' 2 ',' 3+ ',' NaN '], ' Married ': [' No ',' Yes ​​',' Yes ​​',' Yes ​​',' No ']}) ', Астип (int) не будет работать. Я думаю, что преобразование 'df = df.apply (lambda x: x.map ({'0': 0, '1': 1, '2': 2, '3': 3}) - это лучше метод для его очистки. – FrankZhu

Смежные вопросы