我有一个多索引数据框,如下所示:
In[13]: df
Out[13]:
Last Trade
Date Ticker
1983-03-30 CLM83 1983-05-18
CLN83 1983-06-17
CLQ83 1983-07-18
CLU83 1983-08-19
CLV83 1983-09-16
CLX83 1983-10-18
CLZ83 1983-11-18
1983-04-04 CLM83 1983-05-18
CLN83 1983-06-17
CLQ83 1983-07-18
CLU83 1983-08-19
CLV83 1983-09-16
CLX83 1983-10-18
CLZ83 1983-11-18
索引有两个级别(即' Date'' Ticker')。我想在“最后交易”专栏中应用一个功能。这会让我知道有多少个月将这个' Last Trade'来自索引的日期'日期' 我找到了一个执行计算的函数:
from calendar import monthrange
def monthdelta(d1, d2):
delta = 0
while True:
mdays = monthrange(d1.year, d1.month)[1]
d1 += datetime.timedelta(days=mdays)
if d1 <= d2:
delta += 1
else:
break
return delta
我尝试应用以下函数h,但它返回一个AttributeError:&#39;时间戳&#39;对象没有属性&#39; index&#39;:
In[14]: h = lambda x: monthdelta(x.index.get_level_values(0),x)
In[15]: df['Last Trade'] = df['Last Trade'].apply(h)
如何应用同时使用列和索引值的函数?
感谢您的提示,
答案 0 :(得分:3)
使用df.index.to_series().str.get(0)
获取索引的第一级。
(df['Last Trade'].dt.month - df.index.to_series().str.get(0).dt.month) + \
(df['Last Trade'].dt.year - df.index.to_series().str.get(0).dt.year) * 12
Date Ticker
1983-03-30 CLM83 2
CLN83 3
CLQ83 4
CLU83 5
CLV83 6
CLX83 7
CLZ83 8
1983-04-04 CLM83 1
CLN83 2
CLQ83 3
CLU83 4
CLV83 5
CLX83 6
CLZ83 7
dtype: int64
鉴于df
<强> pd.concat([df for _ in range(10000)])
强>
答案 1 :(得分:3)
尝试使用此功能代替您的功能:
def monthdelta(row):
trade = row['Last Trade'].year*12 + row['Last Trade'].month
date = row['Date'].year*12 + row['Date'].month
return trade - date
df.reset_index().apply(monthdelta, axis=1)
受PiRsquared的启发:
df = df.reset_index()
(df['Last Trade'].dt.year*12 + df['Last Trade'].dt.month) -\
(df['Date'].dt.year*12 + df['Date'].dt.month)
numpy.timedelta64
可以直接用于其他日期计算。但是,这将是几天而不是几个月的形式,因为days in a month are not constant。
的数量def monthdelta(row):
return row['Last Trade'] - row['Date']
df.reset_index().apply(monthdelta, axis=1)
受PiRsquared的启发:
df = df.reset_index()
df['Last Trade'] - df['Date']
选项2当然会更快,因为它涉及更少的计算。选择你喜欢的!
要获取您的索引:df.index = df[['Date', 'Ticker']]