作为一个在数据分析领域花费的时间比编程本身更多的人,只是在寻找一种最佳方法(向大家致敬)。相当简单,大型ETL项目,但用Python手工编码,这是第一次。固定宽度文件正在成功读取到初始PANDAS df中。
我正在尝试添加一个新列,该列具有一个静态的月底日期值(例如,2014-01-31),指示"数据月",以进行进一步的EDW处理。最终,我将使用datetime/timedelta功能将该值作为在实用工具服务器上CRON时自动生成的值进行传递。
我的困惑似乎是,如果我需要引用原始df中的一个索引值来将一个完全不相关的值应用于初始df,那么应该使用哪个函数(apply、mapapply等),以及实现这一点的最优化的Python方法。
目前参考:"Python for Data Analysis",PANDAS Docs。谢谢
编辑
以下是一些固定宽度数据的一个小例子:
5151022314
5113 22204
111 20018
以下是一些将其读入PANDAS df:的代码
import pandas as pd
import numpy as np
path = 'C:UsersOfficeDesktopexample data.txt'
widths = [2, 3, 5]
names = (['STATE_CD', 'CNTY_CD', 'ZIP_CD',])
df = pd.read_fwf(path, names=names, widths=widths, header=0)
对于上面的示例日期,这应该返回类似这样的内容作为df:
STATE_CD,CNTY_CD,ZIP_CD
51,510,22314
51,1 ,22204
11,3 ,20018
我想做的是为所有行添加一个像这样的列"DATA_MM":
STATE_CD,CNTY_CD,ZIP_CD, DATA_MM
51,510,22314,2014-01-31
51,1 ,22204,2014-01-31
11,3 ,20018,2014-01-31
最终,我希望利用这样的东西来产生价值,当这个每月的工作启动时自动应用:
import datetime
today = datetime.date.today()
first = datetime.date(day=1, month=today.month, year=today.year)
lastMonth = first - datetime.timedelta(days=1)
print lastMonth.strftime("%Y-%m-%d")
如果要用不依赖于原始DataFrame的新值填充列,则不需要引用原始索引。您可以通过简单地为新列分配新值来填充该列:
df["DATA_MM"] = date
您可以使用datetime
和calendar
:来获取本月的最后一天
import datetime
import calendar
today = datetime.date.today()
y = today.year
m = today.month
eom = datetime.date(y, m, calendar.monthrange(y, m)[1])
df["DATA_MM"] = eom
monthrange
返回一个包含该月的第一天和最后一天的元组,因此[1]
引用该月的最后一天。您也可以使用@Alexander的方法来查找最后一天的日期,并将其直接分配给列,而不是apply
。
假设您的DataFrame名为df,它有一个时间戳的日期列,您希望获得月底(EOM)值:
df['EOM date'] = df.date.apply(lambda x: x.to_period('M').to_timestamp('M'))
您将对象强制为Pandas Period对象,然后返回月末时间戳,因此这可能不是最有效的方法。
以下是一个具有一些性能统计数据的替代实现:
dates = pd.date_range('2000-1-1', '2015-1-1')
df = pd.DataFrame(dates, columns=['date'])
%%timeit
df.date.apply(lambda x: x.to_period('M').to_timestamp('M'))
10 loops, best of 3: 161 ms per loop
%%timeit
df.date.apply(lambda x: x + pd.datetools.MonthEnd())
1 loops, best of 3: 177 ms per loop
只需从当前日期获得月底日期的DATETIME.DATE(根据下面的请求)就可以实现如下:
pd.Timestamp(dt.datetime.now()).to_period('M').to_timestamp('M').date()