Python 有没有更快的方法来查找数据帧中常量值的范围?
我想找出数据帧中常量值的最长持续时间。例如,给定下面的数据帧,最长持续时间应为30分钟(当值=2时) (注意:日期和时间间隔并不总是一致的。) 我通过查找Python 有没有更快的方法来查找数据帧中常量值的范围?,python,pandas,dataframe,datetime,Python,Pandas,Dataframe,Datetime,我想找出数据帧中常量值的最长持续时间。例如,给定下面的数据帧,最长持续时间应为30分钟(当值=2时) (注意:日期和时间间隔并不总是一致的。) 我通过查找df.value.diff().abs()==0的索引找到了它,构建了一个复杂的函数来迭代该列表并计算范围 由于实际的数据帧比这个示例大得多,是否有一个快捷函数或一种更快的方法来获得它而无需多次迭代 多谢各位 编辑: 在我的例子中,相同的值可以出现在其他条纹中。一个更合适的例子是 d = {'date_time': ['2016-01-01 1
df.value.diff().abs()==0
的索引找到了它,构建了一个复杂的函数来迭代该列表并计算范围
由于实际的数据帧比这个示例大得多,是否有一个快捷函数或一种更快的方法来获得它而无需多次迭代
多谢各位
编辑:
在我的例子中,相同的值可以出现在其他条纹中。一个更合适的例子是
d = {'date_time': ['2016-01-01 12:00:00', '2016-01-01 12:15:00',
'2016-01-01 12:30:00', '2016-01-01 12:45:00',
'2016-01-01 13:00:00', '2016-01-01 13:15:00',
'2016-01-01 13:30:00', '2016-01-01 13:45:00',
'2016-01-01 14:00:00', '2016-01-01 14:05:00'],
'value': [1,2,2,2,4,5,5,7,5,5]}
df = pd.DataFrame(data=d)
df['date_time'] = pd.to_datetime(df['date_time'])
print(df)
date_time value
0 2016-01-01 12:00:00 1
1 2016-01-01 12:15:00 2
2 2016-01-01 12:30:00 2
3 2016-01-01 12:45:00 2
4 2016-01-01 13:00:00 4
5 2016-01-01 13:15:00 5
6 2016-01-01 13:30:00 5
7 2016-01-01 13:45:00 7
8 2016-01-01 14:00:00 5
9 2016-01-01 14:05:00 5
在这种情况下,当value=2时,最长持续时间为30分钟。您可以按value列分组,并使用
.size()
获取每组的大小/长度
import pandas as pd
d = {'date_time': ['2016-01-01 12:00:00', '2016-01-01 12:15:00',
'2016-01-01 12:30:00', '2016-01-01 12:45:00',
'2016-01-01 13:00:00', '2016-01-01 13:15:00',
'2016-01-01 13:30:00', '2016-01-01 13:45:00'],
'value': [1,2,2,2,4,5,5,7]}
df = pd.DataFrame(data=d)
df['date_time'] = pd.to_datetime(df['date_time'])
print(df)
date_time value
0 2016-01-01 12:00:00 1
1 2016-01-01 12:15:00 2
2 2016-01-01 12:30:00 2
3 2016-01-01 12:45:00 2
4 2016-01-01 13:00:00 4
5 2016-01-01 13:15:00 5
6 2016-01-01 13:30:00 5
7 2016-01-01 13:45:00 7
>>> groups = df.groupby('value')
>>> groups.size()
value
1 1
2 3
4 1
5 2
7 1
dtype: int64
.idxmax()
将为您提供可以传递到的最大组的索引。get_groups()
然后,您可以区分最后一个日期和第一个日期(假设它们已排序-如果未排序,则可以排序)
如果value
可以在其他条纹中重复,则可以使用以下方法进行分组:
groups = df.groupby((df.value != df.value.shift()).cumsum())
更新:任何条纹的最大持续时间
>>> groups = df.groupby((df.value != df.value.shift()).cumsum())
>>> last = groups.last()
>>> max_duration = (last.date_time - groups.first().date_time).nlargest(1)
>>> max_duration.iat[0]
Timedelta('0 days 00:30:00')
>>> last.loc[max_duration.index].value.iat[0]
2
您可以使用pd.pivot_表获取每个值的最小和最大日期时间值,然后计算它们之间的持续时间并提取最长的时间
import pandas as pd
import numpy as np
d = {'date_time': ['2016-01-01 12:00:00', '2016-01-01 12:15:00',
'2016-01-01 12:30:00', '2016-01-01 12:45:00',
'2016-01-01 13:00:00', '2016-01-01 13:15:00',
'2016-01-01 13:30:00', '2016-01-01 13:45:00'],
'value': [1,2,2,2,4,5,5,7]}
df = pd.DataFrame(data=d)
df['date_time'] = pd.to_datetime(df['date_time'])
df_pivot = pd.pivot_table(df, index='value', values='date_time', aggfunc=[np.min,np.max])
df_pivot['duration'] = df_pivot.iloc[:, 1] - df_pivot.iloc[:, 0]
print(df_pivot[df_pivot['duration'] == max(df_pivot['duration'])])
groupby
+nlargest
创建跟踪更改的分组系列
groupr = df.value.ne(df.value.shift()).cumsum()
创建一个映射字典,可以将groupr
键转换为df.value
列中的实际value
mapper = dict(zip(groupr, df.value))
现在我们分组并使用ptp
和nlargest
。最后,我们使用rename
和mapper
将索引
值(即groupr
值)转换回值
值(这有点混乱)
索引中的2
是持续时间最长的值。0天00:30:00
是最长的持续时间
工具书类
是否可以在另一个条纹中再次出现value
值?@Karlthorton相同的值可以在另一个条纹中再次出现,这将是一个不同的条纹。谢谢您的回答!这比我的问题更全面。.shift()和cumsum技术非常适合我的情况。事实上,上面的方法获取了值的最长条纹,并给出了该条纹的持续时间,而不是任何条纹的最长持续时间。因此,我可能没有正确回答您的问题。更新我的答案的最长持续时间的任何连胜。谢谢。我喜欢你的答案给出了价值和持续时间。但是,当该值再次出现在另一个条纹中时,它不适用。请参阅我更新的示例。如果您能更新您的答案,我将不胜感激。谢谢:)看看这对你是否有意义。它现在返回正确的结果。但是“应用”似乎在我的实际数据帧上花费了很长时间,而实际数据帧要大得多。我想知道是否有更快的解决办法。谢谢。对不起,我没有把问题说清楚。请参阅我更新的示例。该值实际上可以出现在其他条纹中,但不应计算在内。非常感谢。
groupr = df.value.ne(df.value.shift()).cumsum()
mapper = dict(zip(groupr, df.value))
df.groupby(groupr).date_time.apply(np.ptp).nlargest(1).rename(mapper)
value
2 0 days 00:30:00
Name: date_time, dtype: timedelta64[ns]