只是寻找一种最好的方法,因为那些花费更多时间在数据分析上而不是编程的人(给大家提示)。非常简单,大型的ETL项目,但是用Python编写它是第一个。固定宽度文件正在成功读入初始PANDAS df。
我正在尝试添加一个新列,其中包含一个静态的月末日期值(例如,2014-01-31),表示"数据月"用于进一步的EDW处理。最后,我将使用datetime / timedelta功能将此值作为自动生成,当我在实用程序服务器上进行CRON时。
我的困惑似乎是关于使用哪个函数(apply,mapapply等),如果我需要引用原始df中的索引值以将完全不相关的值应用于初始df,并且最优化, pythonic方式来实现这一目标。
目前引用:" Python for Data Analysis",PANDAS Docs。谢谢!
修改
以下是一些固定宽度数据的小例子:
5151022314
5113 22204
111 20018
以下是将其读入PANDAS df的一些代码:
import pandas as pd
import numpy as np
path = 'C:\Users\Office\Desktop\example 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")
答案 0 :(得分:1)
如果要使用不依赖于原始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]
会引用该月的最后一天。您也可以使用@Alex的方法查找最后一天的日期,并将其直接分配给列而不是apply
。
答案 1 :(得分:0)
假设您的DataFrame名为df,并且它有一个Datestamps的日期列,您希望为其获取月末(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()