2016-11-22 4 views
0

панды dataframe:Как разделить значение dataframe pandas по первой строке каждой группой?

>>> df 
        sales net_pft 
STK_ID RPT_Date     
002138 20140930 3.325 0.607 
     20150930 3.619 0.738 
     20160930 4.779 0.948 
600004 20140930 13.986 2.205 
     20150930 14.226 3.080 
     20160930 15.499 3.619 
600660 20140930 31.773 5.286 
     20150930 31.040 6.333 
     20160930 40.062 7.186 

Просто хочу знать, как получить результат в качестве значения для каждой строки делится на его первой строке каждой группы, например:

    sales net_pft 
STK_ID RPT_Date     
002138 20140930 1.000 1.000 
     20150930 1.088 1.216 
     20160930 1.437 1.562 
600004 20140930 1.000 1.000 
     20150930 1.017 1.397 
     20160930 1.108 1.641 
600660 20140930 1.000 1.000 
     20150930 0.977 1.198 
     20160930 1.261 1.359 

Спасибо,

ответ

1
import pandas as pd 

df = pd.DataFrame({'RPT_Date': ['20140930', '20150930', '20160930', '20140930', '20150930', '20160930', '20140930', '20150930', '20160930'], 'STK_ID': ['002138', '002138', '002138', '600004', '600004', '600004', '600660', '600660', '600660'], 'net_pft': [0.607, 0.738, 0.948, 2.205, 3.080, 3.619, 5.286, 6.333, 7.186], 'sales': [3.325, 3.619, 4.779, 13.986, 14.226, 15.499, 31.773, 31.040, 40.062]}) 
df = df.set_index(['STK_ID','RPT_Date']) 

firsts = (df.groupby(level=['STK_ID']).transform('first')) 
result = df/firsts 

дает

    net_pft  sales 
STK_ID RPT_Date      
002138 20140930 1.000000 1.000000 
     20150930 1.215815 1.088421 
     20160930 1.561779 1.437293 
600004 20140930 1.000000 1.000000 
     20150930 1.396825 1.017160 
     20160930 1.641270 1.108180 
600660 20140930 1.000000 1.000000 
     20150930 1.198070 0.976930 
     20160930 1.359440 1.260882 

Основной трик выше, чтобы использовать groupby/transform('first'), чтобы создать DataFrame , который имеет такую ​​же форму, как df, но чьи значения приходят из первой строки каждой группы:

firsts = df.groupby(level=['STK_ID']).transform('first') 
#     net_pft sales 
# STK_ID RPT_Date     
# 002138 20140930 0.607 3.325 
#  20150930 0.607 3.325 
#  20160930 0.607 3.325 
# 600004 20140930 2.205 13.986 
#  20150930 2.205 13.986 
#  20160930 2.205 13.986 
# 600660 20140930 5.286 31.773 
#  20150930 5.286 31.773 
#  20160930 5.286 31.773 

Хотя это расточительный использование памяти, это, скорее всего, самый быстрый способ получить желаемый результат, поскольку он избегает циклирования через группы в Python.


Если приведенный выше код вызывает в панде версии 0.13 с TypeError: Transform function invalid for data types, вы можете попробовать использовать этот обходной путь:

result = list() 
for key, grp in df.groupby(level=['STK_ID']): 
    result.append(grp/grp.iloc[0]) 
result = pd.concat(result) 
print(result) 
+0

Я использую панд 13,0, встречаются проблемы, как: >>> первого = df.groupby (level = ['STK_ID']). transform ('first') Traceback (последний последний звонок): Файл «», строка 1, in Файл «C: \ Anaconda \ lib \ site-packages \ pandas \ core \ groupby.py ", строка 2319, в преобразовании return self._transform_item_by_item (obj, fast_path) Файл «C: \ Anaconda \ lib \ site-packages \ pandas \ core \ groupby.py», строка 2386, в _transform_item_by_item raise TypeError ('Функция преобразования недопустима для типов данных') TypeError: функция преобразования недопустима для типов данных – bigbug

+0

Каковы dtypes столбцов в 'df'? Пожалуйста, напишите 'df.info()'. – unutbu

+0

>>> df.info() <класс 'pandas.core.frame.DataFrame'> мультииндексных: 9 записей, (002138, 20140930) к (600660, 20160930) столбцы данных (всего 2 колонки): продаж 9 ненулевыми float64 net_pft 9 ненулевого float64 dtypes: float64 (2) >>> – bigbug

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

  • Нет связанных вопросов^_^