#python #date #for-loop #sum #slice
Вопрос:
У меня есть набор данных, как показано ниже
data = {'ReportingDate':['2013/5/31','2013/5/31','2013/5/31','2013/5/31','2013/5/31','2013/5/31',
'2013/6/28','2013/6/28',
'2013/6/28','2013/6/28','2013/6/28'],
'MarketCap':[' ',0.35,0.7,0.875,0.7,0.35,' ',1,1.5,0.75,1.25],
'AUM':[3.5,3.5,3.5,3.5,3.5,3.5,5,5,5,5,5],
'weight':[' ',0.1,0.2,0.25,0.2,0.1,' ',0.2,0.3,0.15,0.25]}
# Create DataFrame
df = pd.DataFrame(data)
df.set_index('Reporting Date',inplace=True)
df
Просто образец набора данных из 8000 строк.
Отчетная дата начинается с 2013/5/31 по 2015/10/30. Он включает в себя данные за все месяцы в течение вышеуказанного периода. Но только в последний день каждого месяца. В первой строке каждого месяца есть две недостающие данные. Я знаю, что
- сумма веса за каждый месяц равна 1
- вес*AUM равен рыночной капитализации
Я могу использовать нижеприведенную строку, чтобы получить нужный мне ответ, только в течение одного месяца
a= (1-df["2013-5"].iloc[1:]['weight'].sum())
b= a* AUM
df.iloc[1,0]=b
df.iloc[1,2]=a
Как я могу использовать цикл для получения данных за весь период? Спасибо
Ответ №1:
Один из способов использования pandas.DataFrame.groupby
:
# If whitespaces are indeed whitespaces, not nan
df = df.replace("s ", np.nan, regex=True)
# If not already datatime series
df.index = pd.to_datetime(df.index)
s = df["weight"].fillna(1) - df.groupby(df.index.date)["weight"].transform(sum)
df["weight"] = df["weight"].fillna(s)
df["MarketCap"] = df["MarketCap"].fillna(s * df["AUM"])
Примечание: Это предполагает, что даты всегда являются только последним днем, так что это эквивалентно группировке по годам и месяцам. Если это не так, попробуйте:
s = df["weight"].fillna(1) - df.groupby(df.index.strftime("%Y%m"))["weight"].transform(sum)
Выход:
MarketCap AUM weight
ReportingDate
2013-05-31 0.350 3.5 0.10
2013-05-31 0.525 3.5 0.15
2013-05-31 0.700 3.5 0.20
2013-05-31 0.875 3.5 0.25
2013-05-31 0.700 3.5 0.20
2013-05-31 0.350 3.5 0.10
2013-06-28 0.500 5.0 0.10
2013-06-28 1.000 5.0 0.20
2013-06-28 1.500 5.0 0.30
2013-06-28 0.750 5.0 0.15
2013-06-28 1.250 5.0 0.25
Комментарии:
1. Спасибо. поскольку ГОД моей отчетной даты также меняется с 2013 на 2015 год, должен ли я группироваться по месяцам и годам? У меня есть 2013-05 2014-05 2015-05
2. Я получаю эту ошибку во второй строке; Ошибка типа: может только объединить str (не «плавающий») в str
3. Я думаю, что некоторые из ваших элементов (я предполагаю, что пробелы?) являются строковыми. Может им помочь
nan
. Проверьте мои обновления.