我有这样的每小时csv数据按天这样排序数百天:
2011.05.16,00:00,1.40893
2011.05.16,01:00,1.40760
2011.05.16,02:00,1.40750
2011.05.16,03:00,1.40649
我想计算每小时设定每日最高值的次数,所以如果在00:00我的最大值是2011.05.16天,我加1到00:00等等。要做到这一点,我用一个循环来计算像索引一样的小时:
def graph():
Date, Time, High = np.genfromtxt(myPath, delimiter=",",
unpack = True, converters={0:date_converter})
numList = [""] * 24
index=0
hour=0
count = [0] * 24
for eachHour in Time:
numList[hour] += str(High[index])
index += 1
hour +=1
if hour == 24:
higher = (numList.index(max(numList)))
count[higher] += 1
hour = 0
numList = [""] * 24
问题在于,在我的数据中经常存在缺少一些小时的间隙,但循环无法识别它并继续将值放在下一小时索引中。我到处搜索,但我是编程的新手,这是我的第一个“复杂”工作,所以我需要更具体的答案,以了解它是如何工作的。 那么你如何按照解释的方式计算每小时的频率? 最终结果应该是:
00:00 n time max of the day
01:00 n time max of the day
02:00 n time max of the day
etc
答案 0 :(得分:4)
首先阅读csv:
In [11]: df = pd.read_csv('foo.csv', sep=',', header=None, parse_dates=[[0, 1]])
In [12]: df.columns = ['date', 'val']
In [13]: df.set_index('date', inplace=True)
In [14]: df
Out[14]:
val
date
2011-05-16 00:00:00 1.40893
2011-05-16 01:00:00 1.40760
2011-05-16 02:00:00 1.40750
2011-05-16 03:00:00 1.40649
使用resample来获取每天的最大值:
In [15]: day_max = df.resample('D', how='max')
检查每个值是否为最大日期:
In [16]: df['is_day_max'] = day_max.lookup(df.index.normalize(), len(df) * ['val']) == df.val
In [17]: df
Out[17]:
val is_day_max
date
2011-05-16 00:00:00 1.40893 True
2011-05-16 01:00:00 1.40760 False
2011-05-16 02:00:00 1.40750 False
2011-05-16 03:00:00 1.40649 False
然后每小时总结一下这些:
In [18]: df.groupby(df.index.time)['is_day_max'].sum()
Out[18]:
00:00:00 1
01:00:00 0
02:00:00 0
03:00:00 0
Name: is_day_max, dtype: float64
答案 1 :(得分:3)
带有pandas的解决方案:假设您有一个日期为index的数据框,您可以先添加一列来指示每天的最大值,然后按小时分组并对出现次数求和:
In [32]: df['daily_max'] = df.groupby(df.index.date).transform(lambda x: x==x.max())
In [33]: df
Out[33]:
value daily_max
date_time
2011-05-16 00:00:00 1.40893 True
2011-05-16 01:00:00 1.40760 False
2011-05-16 02:00:00 1.40750 False
2011-05-16 03:00:00 1.40649 False
2011-05-17 02:00:00 1.40893 True
2011-05-17 03:00:00 1.40760 False
2011-05-17 04:00:00 1.40750 False
2011-05-17 05:00:00 1.40649 False
2011-05-18 02:00:00 1.40893 True
2011-05-18 03:00:00 1.40760 False
2011-05-18 04:00:00 1.40750 False
2011-05-18 05:00:00 1.40649 False
In [34]: df.groupby(df.index.time)['daily_max'].sum()
Out[34]:
00:00:00 1
01:00:00 0
02:00:00 2
03:00:00 0
04:00:00 0
05:00:00 0
Name: daily_max, dtype: float64
使用较旧的pandas版本,这将得到与上面相同的结果(假设您的df
具有DatetimeIndex):
df['date'] = [t.date() for t in df.index.to_pydatetime()]
df['time'] = [t.time() for t in df.index.to_pydatetime()]
df['daily_max'] = df.groupby('date')['value'].transform(lambda x: x==x.max())
df.groupby('time')['daily_max'].sum()
我在此示例中使用的数据框:
from StringIO import StringIO
s="""2011.05.16,00:00,1.40893
2011.05.16,01:00,1.40760
2011.05.16,02:00,1.40750
2011.05.16,03:00,1.40649
2011.05.17,02:00,1.40893
2011.05.17,03:00,1.40760
2011.05.17,04:00,1.40750
2011.05.17,05:00,1.40649
2011.05.18,02:00,1.40893
2011.05.18,03:00,1.40760
2011.05.18,04:00,1.40750
2011.05.18,05:00,1.40649"""
df = pd.read_csv(StringIO(s), header=None, names=['date', 'time', 'value'], parse_dates=[['date', 'time']])
df = df.set_index('date_time')
答案 2 :(得分:0)
我不确定你想要计算的是什么,但这就是我计算数据集中值的方法
from time import strptime,strftime
time_format="%H:%M"
date_format="%Y.%m.%d"
def date_values(flo):
for line in flo:
try:
date_str, time_str, value = line.split(',')
date = strptime(date_str,"%Y.%m.%d")
time = strptime(time_str,"%H:%M")
value = float(value)
yield (date, time, value)
except ValueError:
pass
def day_values(flo):
days = {}
for date,time,value in date_values(flo):
try:
days[date].append(value)
except KeyError:
days[date] = [ value ]
return days
if __name__ == '__main__':
from sys import stdin
for day,values in day_values(stdin).items():
print("{0}: {1} (max of {2})".format(
strftime(date_format, day),
values,
max(values)))
date_values函数将返回一个生成器,该生成器迭代数据输入的有效行。 day_values函数使用生成器构造一个字典,其中键是日期,值是该日期的值数组。根据您的描述,我不确定时间是如何发挥作用的,如果您可以澄清,或者提供一个更大的数据集以及您希望看到的结果示例,我可以对此进行扩展。
如果我将该文件命名为freq_count.py
并假设您的数据集位于名为data
的文件中,我会
$ python freq_count.py < data
2011.05.16: [1.40893, 1.4076, 1.4075, 1.40649] (max of 1.40893)
计算最大值的频率:
def count_freq(values):
return len( [ v for v in values if v == max(values) ] )
使用列表推导来生成包含values
输入中所有最大值的列表,然后获取结果列表的长度。