我有一个数据框,想根据公式替换每个单元格值 new_val = current_val/#days 该月。假设数据框如下所示:
2012 2013 2014
Jan 10 12 11
Feb 8 9 10
Mar 11 11 13
然后,如果 2012 年 1 月的天数为 31,则 2012 年 1 月对应的新单元格值为 10/31。同样,2014 年 3 月的值为 13/31,依此类推。
我正在考虑应用 applymap 函数,但我在语法上苦苦挣扎:
df.applymap(lambda x: x/(monthrange(A,B)[1]))
其中 A = 年,B = 月。我想知道是否有人可以帮助我为 A 和 B 建立适当的索引。
输出将是:
2012 2013 2014
Jan 0.3226 0.3870 0.3548
Feb 0.2758 0.3214 0.3571
Mar 0.3548 0.3548 0.4193
请您参考如下方法:
使用df.applymap(func),函数func 只传递给DataFrame 值。它不会传递相应的索引和列标签。所以我 在此处看不到可以使用 df.applymap 的方法。
相反,您可以解压df,并使用其索引、df.stack().index 和pd.to_datetime 来解析将索引和列标签转换为日期:
result = df.stack()
# Jan 2012 10
# 2013 12
# 2014 11
# Feb 2012 8
# 2013 9
# 2014 10
# Mar 2012 11
# 2013 11
# 2014 13
# dtype: int64
dates = pd.to_datetime([' '.join(item) for item in result.index])
# DatetimeIndex(['2012-01-01', '2013-01-01', '2014-01-01', '2012-02-01',
# '2013-02-01', '2014-02-01', '2012-03-01', '2013-03-01',
# '2014-03-01'],
# dtype='datetime64[ns]', freq=None, tz=None)
然后使用 DatetimeIndex.days_in_month 属性找出数字 每个月的天数:
days = dates.days_in_month
# array([31, 31, 31, 29, 28, 28, 31, 31, 31], dtype=int32)
现在将 result 除以每个月的天数:
In [140]: result/days
Out[140]:
Jan 2012 0.322581
2013 0.387097
2014 0.354839
Feb 2012 0.275862
2013 0.321429
2014 0.357143
Mar 2012 0.354839
2013 0.354839
2014 0.419355
dtype: float64
并拆叠以获得所需的结果:
(df.stack()/days).unstack()
import numpy as np
import pandas as pd
df = pd.DataFrame({'2012': [10, 8, 11], '2013': [12, 9, 11], '2014': [11, 10, 13]},
index='Jan Feb Mar'.split())
result = df.stack()
dates = pd.to_datetime([' '.join(item) for item in result.index])
days = dates.days_in_month
result = (result / days).unstack()
print(result)
产量
2012 2013 2014
Jan 0.322581 0.387097 0.354839
Feb 0.275862 0.321429 0.357143
Mar 0.354839 0.354839 0.419355
对于旧版本的 Pandas(v.0.16 之前),您可以使用
days = (dates + pd.DateOffset(months=1, days=-1)).day
代替
days = dates.days_in_month
计算每个月的天数。
