我有一个包含数千行的CSV文件。该文件有3列日期,时间和值。我想先遍历日期列,然后再遍历时间列,然后在两个特定时间之间添加值。熊猫有没有实现这一目标的功能?以下是我的示例CSV。日期不是连续的,而是按升序排列。
Date Time Value
29-Jan-18 11:00 10
29-Jan-18 12:00 11
29-Jan-18 13:00 12
29-Jan-18 14:00 13
31-Jan-18 11:00 90
31-Jan-18 12:00 91
31-Jan-18 13:00 92
31-Jan-18 14:00 93
我正在寻找输出为“对于18年1月29日,对于时间11到13,这些值的总和为33。”
不完全是11-12,但是有一系列。计算将针对9-10,10-11,11-13,13-15进行,但是在CSV文件中,每小时都有一次。
答案 0 :(得分:0)
主要思想是将日期/时间列打入datetime
对象中,然后使用这些对象进行日期过滤。我以为它们是字符串开头。
我不确定您的日期如何输入,但是希望您能弄清楚如何从中创建datetime
对象。如果没有,请告诉我,我们可以进行更新。这是一个示例,说明如何按日期过滤并求和开始/结束日期的值:
import numpy as np
import pandas as pd
import datetime
cols = ["Date", "Time", "Value"]
rows = [["29-Jan-18", "11:00", 10],
["29-Jan-18", "12:00", 11],
["29-Jan-18", "13:00", 12],
["29-Jan-18", "14:00", 13],
["31-Jan-18", "11:00", 90],
["31-Jan-18", "12:00", 91],
["31-Jan-18", "13:00", 92],
["31-Jan-18", "14:00", 93]]
df = pd.DataFrame(rows, columns=cols)
df['datetime_str'] = df['Date'].str.cat(df['Time'].astype(str), sep=" ")
df['datetime'] = df['datetime_str'].apply(lambda d: datetime.datetime.strptime(d, '%d-%b-%y %H:%M'))
print(df)
print()
# Hopefully you can figure out how to beat incoming start/end date into datetime.
# If not, let me know how the start/end are coming in and we can write a function to do it
start_date = datetime.datetime.strptime("29-Jan-18 11:00", '%d-%b-%y %H:%M')
end_date = datetime.datetime.strptime("29-Jan-18 13:00", '%d-%b-%y %H:%M')
value_sum = df[ (df['datetime'] >= start_date) & (df['datetime'] <= end_date) ]['Value'].sum()
print("Value sum from " + str(start_date) + " to " + str(end_date) + ": ", value_sum)
# Works accross days as well
start_date = datetime.datetime.strptime("29-Jan-18 13:00", '%d-%b-%y %H:%M')
end_date = datetime.datetime.strptime("31-Jan-18 13:00", '%d-%b-%y %H:%M')
value_sum = df[ (df['datetime'] >= start_date) & (df['datetime'] <= end_date) ]['Value'].sum()
print("Value sum from " + str(start_date) + " to " + str(end_date) + ": ", value_sum)
这将输出:
Date Time Value datetime_str datetime
0 29-Jan-18 11:00 10 29-Jan-18 11:00 2018-01-29 11:00:00
1 29-Jan-18 12:00 11 29-Jan-18 12:00 2018-01-29 12:00:00
2 29-Jan-18 13:00 12 29-Jan-18 13:00 2018-01-29 13:00:00
3 29-Jan-18 14:00 13 29-Jan-18 14:00 2018-01-29 14:00:00
4 31-Jan-18 11:00 90 31-Jan-18 11:00 2018-01-31 11:00:00
5 31-Jan-18 12:00 91 31-Jan-18 12:00 2018-01-31 12:00:00
6 31-Jan-18 13:00 92 31-Jan-18 13:00 2018-01-31 13:00:00
7 31-Jan-18 14:00 93 31-Jan-18 14:00 2018-01-31 14:00:00
Value sum from 2018-01-29 11:00:00 to 2018-01-29 13:00:00: 33
Value sum from 2018-01-29 13:00:00 to 2018-01-31 13:00:00: 298
答案 1 :(得分:0)
您可以通过使用GoogleCloudStorageReadChannel
方法来实现。
首先,您需要合并日期列和时间列以创建单个日期时间索引。假设您的两列是字符串(如果不是,则可以在它们上调用resample
),您可以串联这些列,将它们转换为as_type(str)
列,然后将该datetime
列转换为DataFrame的datetime
。
然后调用DatetimeIndex
,将规则设置为resample
,以创建宽度为3小时的垃圾箱,并将'3H'
设置为上午11点开始(当然,如果您需要/可以更改此设置) to)和base=11
。
这里是一个例子:
sum
并使用您给定的数据作为输入的import pandas as pd
import datetime as dt
df.index = pd.DatetimeIndex(pd.to_datetime(df.Date.str.cat(df.Time, sep=' ')))
df = df.resample('1H').sum() # to fill missing values
# get values for 9 & 10
df1 = df[(dt.time(9) <= df.index.time) & (df.index.time <= dt.time(10))]
# get values for 11-13 & 13-15
two_hour_ranges = df[df.index.time >= dt.time(11)].resample('2H', base=11).sum()
df2 = two_hour_ranges[(dt.time(11) <= two_hour_ranges.index.time) & (two_hour_ranges.index.time < dt.time(15))]
# merge
df = pd.concat([df1, df2]).sort_index()
的示例输出(我在1/29和1/31上分别添加了9:00和10:00的值):
df
以下是 Value
Date
2018-01-29 09:00:00 4
2018-01-29 10:00:00 5
2018-01-29 11:00:00 21
2018-01-29 13:00:00 25
2018-01-30 09:00:00 0
2018-01-30 10:00:00 0
2018-01-30 11:00:00 0
2018-01-30 13:00:00 0
2018-01-31 09:00:00 70
2018-01-31 10:00:00 80
2018-01-31 11:00:00 181
2018-01-31 13:00:00 185
上的文档:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.resample.html