繁体   English   中英

遍历熊猫数据框

[英]Iterating through a pandas dataframe

我有一个pandas数据框,其中一列表示在其下一行中另一列中的位置值是否发生了变化。 举个例子,

2013-02-05 19:45:00   (39.94, -86.159)     True
2013-02-05 19:50:00   (39.94, -86.159)     True
2013-02-05 19:55:00   (39.94, -86.159)    False
2013-02-05 20:00:00  (39.777, -85.995)    False
2013-02-05 20:05:00  (39.775, -85.978)     True
2013-02-05 20:10:00  (39.775, -85.978)     True
2013-02-05 20:15:00  (39.775, -85.978)    False
2013-02-05 20:20:00   (39.94, -86.159)     True
2013-02-05 20:30:00   (39.94, -86.159)    False

所以,我想做的是逐行通过此数据帧,并检查False的行。 然后(可以添加另一列),该位置具有在该位置花费的总“连续”时间。 可以像上面的示例一样再次访问相同的地方。 在这种情况下,将其视为单独的条件。 因此,对于上面的示例,类似:

2013-02-05 19:45:00   (39.94, -86.159)     True    0
2013-02-05 19:50:00   (39.94, -86.159)     True    0
2013-02-05 19:55:00   (39.94, -86.159)    False   15
2013-02-05 20:00:00  (39.777, -85.995)    False    5  
2013-02-05 20:05:00  (39.775, -85.978)     True    0
2013-02-05 20:10:00  (39.775, -85.978)     True    0
2013-02-05 20:15:00  (39.775, -85.978)    False   15
2013-02-05 20:20:00   (39.94, -86.159)     True    0 
2013-02-05 20:25:00   (39.94, -86.159)    False   10

然后,我将绘制每天使用hist()函数花费的这些“连续”时间的直方图。 我如何通过遍历数据帧从第一个数据帧中获取第二个数据帧? 我是python和pandas的新手,真正的数据文件很大,因此,我将需要相当有效的工具。

这是另一种

df['group'] = (df.condition == False).astype('int').cumsum().shift(1).fillna(0)

df
             date    long     lat condition  group
2/5/2013 19:45:00  39.940 -86.159      True      0
2/5/2013 19:50:00  39.940 -86.159      True      0
2/5/2013 19:55:00  39.940 -86.159     False      0
2/5/2013 20:00:00  39.777 -85.995     False      1
2/5/2013 20:05:00  39.775 -85.978      True      2
2/5/2013 20:10:00  39.775 -85.978      True      2
2/5/2013 20:15:00  39.775 -85.978     False      2
2/5/2013 20:20:00  39.940 -86.159      True      3
2/5/2013 20:25:00  39.940 -86.159     False      3

df['result'] = df.groupby(['group']).date.transform(lambda sdf: 5 *len(sdf))

df
             date    long     lat condition  group result
2/5/2013 19:45:00  39.940 -86.159      True      0     15
2/5/2013 19:50:00  39.940 -86.159      True      0     15
2/5/2013 19:55:00  39.940 -86.159     False      0     15
2/5/2013 20:00:00  39.777 -85.995     False      1      5
2/5/2013 20:05:00  39.775 -85.978      True      2     15
2/5/2013 20:10:00  39.775 -85.978      True      2     15
2/5/2013 20:15:00  39.775 -85.978     False      2     15
2/5/2013 20:20:00  39.940 -86.159      True      3     10
2/5/2013 20:25:00  39.940 -86.159     False      3     10

您将需要0.11-dev。 我认为这将为您提供所需的东西。 请参阅本节: http ://pandas.pydata.org/pandas-docs/dev/timeseries.html#time-deltas了解更多信息,因为timedelta是熊猫支持的较新数据

这是您的数据(为方便起见,我将long / lat分开了,关键是条件列是一个布尔值)

In [137]: df = pd.read_csv(StringIO.StringIO(data),index_col=0,parse_dates=True)

In [138]: df
Out[138]: 
               date    long       lat condition
2013-02-05 19:45:00  39.940   -86.159      True
2013-02-05 19:50:00  39.940   -86.159      True
2013-02-05 19:55:00  39.940   -86.159     False
2013-02-05 20:00:00  39.777   -85.995     False
2013-02-05 20:05:00  39.775   -85.978      True
2013-02-05 20:10:00  39.775   -85.978      True
2013-02-05 20:15:00  39.775   -85.978     False
2013-02-05 20:20:00  39.940   -86.159      True
2013-02-05 20:25:00  39.940   -86.159     False

In [139]: df.dtypes
Out[139]: 
date         float64
long lat     float64
condition       bool
dtype: object

创建一些作为索引的日期列(这些是datetime64 [ns] dtype)

In [140]: df['date'] = df.index   
In [141]: df['rdate'] = df.index

将False的rdate列设置为NaT(np.nan被转换为NaT)

In [142]: df.loc[~df['condition'],'rdate'] = np.nan

从上一个值向前填充NaT

In [143]: df['rdate'] = df['rdate'].ffill()

从日期中减去rdate,这将产生timedelta64 [ns]类型的时差列

In [144]: df['diff'] = df['date']-df['rdate']

In [151]: df
Out[151]: 
                                   date  long lat condition               rdate  \
2013-02-05 19:45:00 2013-02-05 19:45:00   -86.159      True 2013-02-05 19:45:00   
2013-02-05 19:50:00 2013-02-05 19:50:00   -86.159      True 2013-02-05 19:50:00   
2013-02-05 19:55:00 2013-02-05 19:55:00   -86.159     False 2013-02-05 19:50:00   
2013-02-05 20:00:00 2013-02-05 20:00:00   -85.995     False 2013-02-05 19:50:00   
2013-02-05 20:05:00 2013-02-05 20:05:00   -85.978      True 2013-02-05 20:05:00   
2013-02-05 20:10:00 2013-02-05 20:10:00   -85.978      True 2013-02-05 20:10:00   
2013-02-05 20:15:00 2013-02-05 20:15:00   -85.978     False 2013-02-05 20:10:00   
2013-02-05 20:20:00 2013-02-05 20:20:00   -86.159      True 2013-02-05 20:20:00   
2013-02-05 20:25:00 2013-02-05 20:25:00   -86.159     False 2013-02-05 20:20:00   

                        diff  
2013-02-05 19:45:00 00:00:00  
2013-02-05 19:50:00 00:00:00  
2013-02-05 19:55:00 00:05:00  
2013-02-05 20:00:00 00:10:00  
2013-02-05 20:05:00 00:00:00  
2013-02-05 20:10:00 00:00:00  
2013-02-05 20:15:00 00:05:00  
2013-02-05 20:20:00 00:00:00  
2013-02-05 20:25:00 00:05:00  

diff列现在是timedelta64 [ns],因此您希望以分钟为单位的整数(仅供参考,由于熊猫没有类似于日期的时间戳的标量类型Timedelta,因此现在有点笨拙)

(此外,在填充之前,您可能必须对此rdate系列执行shift(),我想我在某处偏离了1)...但这是个主意

In [175]: df['diff'].map(lambda x: x.item().seconds/60)
Out[175]: 
2013-02-05 19:45:00     0
2013-02-05 19:50:00     0
2013-02-05 19:55:00     5
2013-02-05 20:00:00    10
2013-02-05 20:05:00     0
2013-02-05 20:10:00     0
2013-02-05 20:15:00     5
2013-02-05 20:20:00     0
2013-02-05 20:25:00     5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM