python - 根据字典选择 Pandas 数据框的行

标签 python pandas

我有一个只有两列的 Pandas 数据框

          Timestamp       X
0   2017-01-01 00:00:00 18450
1   2017-01-01 00:10:00 13787
2   2017-01-01 00:20:00 3249
3   2017-01-01 00:30:00 44354
4   2017-01-01 00:40:00 50750

时间戳列从月初到月末基本上间隔 10 分钟。要创建示例,可以使用以下代码。

l_data = pd.DataFrame()

l_data['Timestamp'] = pd.date_range(start=pd.Timestamp('2017-01-18 00:00:00'), end=pd.Timestamp('2017-01-20 00:00:00'), freq='10T')
l_data['X'] = random.sample(range(0, 100000), len(l_data)) 

我有一本这样的字典

  {Timestamp('2017-01-18 01:37:19.160000'): Timestamp('2017-01-18 01:37:29.520000'),
 Timestamp('2017-01-18 01:41:04.880000'): Timestamp('2017-01-18 01:41:10.280000'),
 Timestamp('2017-01-18 21:33:52.800000'): Timestamp('2017-01-18 21:40:00.040000'),
 Timestamp('2017-01-18 21:40:02.120000'): Timestamp('2017-01-18 21:50:00.040000'),
 Timestamp('2017-01-18 21:50:02.120000'): Timestamp('2017-01-18 22:00:00.040000'),
 Timestamp('2017-01-18 22:00:02.120000'): Timestamp('2017-01-18 22:01:50.760000'),
 Timestamp('2017-01-18 22:20:22.760000'): Timestamp('2017-01-18 22:25:20.760000'),
 Timestamp('2017-01-18 22:35:52.800000'): Timestamp('2017-01-18 22:40:00.040000')}

字典中的key是开始时间,value是结束时间。我想根据 l_data

中的这个 dict 创建一个名为 L 的列

如果 dict 中的键和值之间的时间大于 5 分钟,我必须在 l_data 中将落在该范围内的时间戳记为 1。

如何以直接的方式在 pandas 中实现这一点,而不是使用多个循环。?

预期的输出是这样的

126 1/18/2017 21:00 43401   0
127 1/18/2017 21:10 290     0
128 1/18/2017 21:20 92509   0
129 1/18/2017 21:30 64545   0
130 1/18/2017 21:40 47780   1
131 1/18/2017 21:50 53293   1
132 1/18/2017 22:00 45634   0
133 1/18/2017 22:10 51462   0
134 1/18/2017 22:20 44736   0
135 1/18/2017 22:30 11697   1
136 1/18/2017 22:40 82587   1
137 1/18/2017 22:50 76250   0
138 1/18/2017 23:00 33307   0
139 1/18/2017 23:10 25851   0
140 1/18/2017 23:20 71131   0
141 1/18/2017 23:30 88015   0
142 1/18/2017 23:40 45577   0
143 1/18/2017 23:50 76761   0
144 1/19/2017 0:00  45363   0

只显示重要的行

最佳答案

我相信你需要:

d = { pd.Timestamp('2017-01-18 21:45:02.120000'): pd.Timestamp('2017-01-18 21:50:29.040000'),
pd.Timestamp('2017-01-18 21:51:02.120000'): pd.Timestamp('2017-01-18 22:52:00.040000'),
pd.Timestamp('2017-01-18 22:52:02.120000'): pd.Timestamp('2017-01-18 22:57:59.760000'),
pd.Timestamp('2017-01-18 23:41:52.800000'): pd.Timestamp('2017-01-18 23:43:00.040000'),
pd.Timestamp('2017-01-18 23:44:52.800000'): pd.Timestamp('2017-01-18 23:50:30.040000'),
pd.Timestamp('2017-01-19 01:10:32.800000'): pd.Timestamp('2017-01-19 01:11:30.040000'),
pd.Timestamp('2017-01-19 01:40:32.800000'): pd.Timestamp('2017-01-19 01:55:30.040000'),
pd.Timestamp('2017-01-19 01:57:32.800000'): pd.Timestamp('2017-01-19 02:04:30.040000')}

l_data = pd.DataFrame()
l_data['Timestamp'] = pd.date_range(start=pd.Timestamp('2017-01-18 20:00:00'), 
                                    end=pd.Timestamp('2017-01-19 04:00:00'), freq='10T')
l_data['expected'] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

#print (l_data)

df = pd.DataFrame({'start': list(d.keys()),'end': list(d.values())})
#fikter by 5 minutes
df = df[(df['end'] - df['start']) > pd.Timedelta(5*60, 's')]

#correct 1 minutes end time
s = df['end'].dt.floor('10T')
df['end1'] = s.where((df['end'] - s) < pd.Timedelta(60, 's'), s + pd.Timedelta(10*60, 's'))
print (df)
                    start                     end                end1
0 2017-01-18 21:45:02.120 2017-01-18 21:50:29.040 2017-01-18 21:50:00
1 2017-01-18 21:51:02.120 2017-01-18 22:52:00.040 2017-01-18 23:00:00
2 2017-01-18 22:52:02.120 2017-01-18 22:57:59.760 2017-01-18 23:00:00
4 2017-01-18 23:44:52.800 2017-01-18 23:50:30.040 2017-01-18 23:50:00
6 2017-01-19 01:40:32.800 2017-01-19 01:55:30.040 2017-01-19 02:00:00
7 2017-01-19 01:57:32.800 2017-01-19 02:04:30.040 2017-01-19 02:10:00

#for each group resample by 10min and add missimg datetimes
v = (df.reset_index()[['start','end1','index']]
       .melt('index')
       .set_index('value')
       .groupby('index')
       .resample('10T')['index']
       .ffill()
       .dropna()
       .index
       .get_level_values(1)
       .unique()
       )
#print (v)

l_data['L'] = l_data['Timestamp'].isin(v).astype(int)
print (l_data.head(20))
             Timestamp  expected  L
0  2017-01-18 20:00:00         0  0
1  2017-01-18 20:10:00         0  0
2  2017-01-18 20:20:00         0  0
3  2017-01-18 20:30:00         0  0
4  2017-01-18 20:40:00         0  0
5  2017-01-18 20:50:00         0  0
6  2017-01-18 21:00:00         0  0
7  2017-01-18 21:10:00         0  0
8  2017-01-18 21:20:00         0  0
9  2017-01-18 21:30:00         0  0
10 2017-01-18 21:40:00         0  0
11 2017-01-18 21:50:00         1  1
12 2017-01-18 22:00:00         1  1
13 2017-01-18 22:10:00         1  1
14 2017-01-18 22:20:00         1  1
15 2017-01-18 22:30:00         1  1
16 2017-01-18 22:40:00         1  1
17 2017-01-18 22:50:00         1  1
18 2017-01-18 23:00:00         1  1
19 2017-01-18 23:10:00         0  0

关于python - 根据字典选择 Pandas 数据框的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53313565/

相关文章:

python - 在 Python 中随机化字符串列表的最佳方法

python - 根据 Pandas 中另一列中值的间隔选择列中值的范围

python - 删除 pandas 数据框中所有具有混合数据类型的行,这些数据类型在多列中包含特定字符串

python - Pandas :合并不同时间的数据

python - 如何在python2.7中使用cv2制作一个新的过滤器并将其应用于图像?

python - 如何迭代编写归并排序?

python - 将 xpath 与 lxml.etree._ElementTree 结合使用

python - 在 Seaborn 中绘制具有类似于 "hue"的多个属性的图形

python - merge_asof 多列

Python - 如何从选定的行号中查找总统的平均高度?