2013-07-17 2 views
27

Я больше знаком с R, но я хотел посмотреть, есть ли способ сделать это в пандах. Я хочу создать счет уникальных значений из одного из моих столбцов dataframe, а затем добавить новый столбец с этими подсчетами в мой исходный фрейм данных. Я пробовал пару разных вещей. Я создал серию pandas, а затем вычислил подсчеты с помощью метода value_counts. Я попытался объединить эти значения с исходным фреймворком данных, но ключи, которые я хочу объединить, находятся в индексе (ix/loc). Любые предложения или решения будут оцененыЯ хочу создать столбец value_counts в моем pandas dataframe

Color Value 
Red 100 
Red 150 
Blue 50 

, и я хотел, чтобы вернуть что-то вроде

Color Value Counts 
Red 100 2 
Red 150 2 
Blue 50 1 
+1

Это популярный вопрос в последнее время. См. Этот вопрос [здесь] (http://stackoverflow.com/questions/17666075/python-pandas-groupby-result/17666287#17666287), который почти идентичен вашей ситуации. – bdiamante

ответ

37
df['Counts'] = df.groupby(['Color'])['Value'].transform('count') 

Например,

In [102]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}) 

In [103]: df 
Out[103]: 
    Color Value 
0 Red 100 
1 Red 150 
2 Blue  50 

In [104]: df['Counts'] = df.groupby(['Color'])['Value'].transform('count') 

In [105]: df 
Out[105]: 
    Color Value Counts 
0 Red 100  2 
1 Red 150  2 
2 Blue  50  1 

Обратите внимание, что transform('count') игнорирует пренебрежимо малый. Если вы хотите считать NaN, используйте transform(len).


Для анонимного редактора: Если вы получаете сообщение об ошибке при использовании transform('count') это может быть связанно с вашей версией Панда слишком старой. Вышеописанное работает с версией pandas 0.15 или новее.

+0

Большое спасибо. Очень полезно. Я пытался применить это к более крупному DataFrame и продолжать получать эту ошибку. «ValueError: неправильное количество элементов прошло 1, индексы подразумевают 4». – user2592989

+2

Попробуйте выбрать только один столбец для преобразования ie df.groupby (['Color']) [] .transform ('count') – user1827356

+0

добавлено в поваренную книгу: http://pandas.pydata.org/pandas-docs/dev /cookbook.html#grouping (docs будет строить завтра) – Jeff

2

Моя первоначальная мысль заключалась в использовании понимания списка, как показано ниже, но, как указывалось в комментарии, это медленнее, чем методы groupby и transform. Я оставлю этот ответ, чтобы продемонстрировать ЧТО НЕ ДЕЛАТЬ:

In [94]: df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}) 
In [95]: df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))] 
In [96]: df 
Out[100]: 
    Color Value Counts 
0 Red 100  2 
1 Red 150  2 
2 Blue  50  1 

[3 rows x 3 columns] 

@ метод unutbu ныряет сложный для DataFrames с несколькими столбцами, которые делают это проще код. Если вы работаете с небольшим фреймом данных, это происходит быстрее (см. Ниже), но в противном случае вы должны использовать NOT.

In [97]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = df.groupby(['Color']).transform('count') 
100 loops, best of 3: 2.87 ms per loop 
In [98]: %timeit df = pd.DataFrame({'Color': 'Red Red Blue'.split(), 'Value': [100, 150, 50]}); df['Counts'] = [sum(df['Color'] == df['Color'][i]) for i in xrange(len(df))] 
1000 loops, best of 3: 1.03 ms per loop 
+3

Пример с 3 строками очень вводит в заблуждение с учетом времени. Попробуйте с большим размером данных, и вы увидите, что метод groupby намного быстрее (я попробовал его с вашим 'df' повторением 1000 раз (' df = pd.concat ([df] * 1000, ignore_index = True) ') и получить 3,6 мс (gropuby) против 29 с (понимание списка)). Кроме того, я думаю, что групповой подход проще. – joris

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