Python PANDAS:新专栏,为所有行应用唯一值

时间:2015-03-25 18:58:56

标签: python python-2.7 date pandas etl

只是寻找一种最好的方法,因为那些花费更多时间在数据分析上而不是编程的人(给大家提示)。非常简单,大型的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")

2 个答案:

答案 0 :(得分:1)

如果要使用不依赖于原始DataFrame的新值填充列,则无需引用原始索引。您可以通过简单地为其分配新值来填充新列:

df["DATA_MM"] = date

您可以使用datetimecalendar来获取当月的最后一天:

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()