Python-遍历属性列表

时间:2018-08-18 17:34:40

标签: python pandas datetime lambda apply

我的数据集中有一个功能是熊猫时间戳对象。它(除其他外)具有以下属性:年,小时,星期几,月。

我可以使用一些蛮力方法基于这些属性来创建新功能:

df["year"] = df["timeStamp"].apply(lambda x : x.year)

df["hour"] = df["timeStamp"].apply(lambda x : x.hour)

。 。

但是,我想遍历一个列表:

nomtimes = ["year", "hour", "month", "dayofweek"]


for i in nomtimes:

  df[i] = df["timeStamp"].apply(lambda x : x.i)

我得到以下AttributeError:'Timestamp'对象没有属性'i',我明白了为什么我会出现此错误。

如何获取带引号的字符串以取消引用,以便可以将其作为属性传递?

3 个答案:

答案 0 :(得分:4)

您只需要tf.keras.Model

getattr()

答案 1 :(得分:3)

在这里不要使用.apply,pandas具有各种内置的实用程序来处理日期时间对象,请在系列对象上使用dt属性:

In [11]: start = datetime(2011, 1, 1)
    ...: end = datetime(2012, 1, 1)
    ...:

In [12]: df = pd.DataFrame({'data':pd.date_range(start, end)})

In [13]: df.dtypes
Out[13]:
data    datetime64[ns]
dtype: object

In [14]: df['year'] = df.data.dt.year

In [15]: df['hour'] = df.data.dt.hour

In [16]: df['month'] = df.data.dt.month

In [17]: df['dayofweek'] = df.data.dt.dayofweek

In [18]: df.head()
Out[18]:
        data  year  hour  month  dayofweek
0 2011-01-01  2011     0      1          5
1 2011-01-02  2011     0      1          6
2 2011-01-03  2011     0      1          0
3 2011-01-04  2011     0      1          1
4 2011-01-05  2011     0      1          2

或者,根据需要使用getattr动态地:

In [24]: df = pd.DataFrame({'data':pd.date_range(start, end)})

In [25]: nomtimes = ["year", "hour", "month", "dayofweek"]
    ...:

In [26]: df.head()
Out[26]:
        data
0 2011-01-01
1 2011-01-02
2 2011-01-03
3 2011-01-04
4 2011-01-05

In [27]: for t in nomtimes:
    ...:     df[t] = getattr(df.data.dt, t)
    ...:

In [28]: df.head()
Out[28]:
        data  year  hour  month  dayofweek
0 2011-01-01  2011     0      1          5
1 2011-01-02  2011     0      1          6
2 2011-01-03  2011     0      1          0
3 2011-01-04  2011     0      1          1
4 2011-01-05  2011     0      1          2

如果必须使用单线,请选择:

In [30]: df = pd.DataFrame({'data':pd.date_range(start, end)})

In [31]: df.head()
Out[31]:
        data
0 2011-01-01
1 2011-01-02
2 2011-01-03
3 2011-01-04
4 2011-01-05

In [32]: df = df.assign(**{t:getattr(df.data.dt,t) for t in nomtimes})

In [33]: df.head()
Out[33]:
        data  dayofweek  hour  month  year
0 2011-01-01          5     0      1  2011
1 2011-01-02          6     0      1  2011
2 2011-01-03          0     0      1  2011
3 2011-01-04          1     0      1  2011
4 2011-01-05          2     0      1  2011

答案 2 :(得分:2)

operator.attrgetter

您可以循环提取属性:

max-width: 100%;
max-height: 100%;

这是一个完整的例子:

from operator import attrgetter

for i in nomtimes:
    df[i] = df['timeStamp'].apply(attrgetter(i))

您的代码将不起作用,因为您尝试传递字符串而不是按名称提取属性。但这不是正在发生的情况:如第一个示例所示,语法不会提供字符串,而是尝试直接访问df = pd.DataFrame({'timeStamp': ['2018-05-05 15:00', '2015-01-30 11:00']}) df['timeStamp'] = pd.to_datetime(df['timeStamp']) nomtimes = ['year', 'hour', 'month', 'dayofweek'] for i in nomtimes: df[i] = df['timeStamp'].apply(attrgetter(i)) print(df) timeStamp year hour month dayofweek 0 2018-05-05 15:00:00 2018 15 5 5 1 2015-01-30 11:00:00 2015 11 1 4

摆脱for循环

您可能会问是否有一种方法可以一次性而不是顺序地从i对象中提取所有属性。 datetime的好处是您可以直接指定多个属性,从而完全避免attrgetter循环:

for

使用dt访问器代替apply

但是pd.Series.apply只是一个薄薄的循环。通常,这不是必需的。借用@ juanpa.arrivillaga的想法,您可以直接通过pd.Series.dt访问器访问属性:

attributes = df['timeStamp'].apply(attrgetter(*nomtimes))
df[nomtimes] = pd.DataFrame(attributes.values.tolist())