ValueError Pandas使用Numpy Arange按时间顺序重复行

时间:2018-06-27 10:52:14

标签: python pandas numpy

我目前正在寻找一种比本link中的解决方案更快的解决方案。问题是,当我的数据达到相对较大的数量(例如100万行)时,它的运行速度相当慢,尤其是当它是秒数而不是原始帖子中的分钟数时。

所以我试图找到一种使用Numpy arange的更有效的方法。但是我遇到了错误

#First- with pd.to_datetime
x = pd.DataFrame({ "ID": np.repeat(df.ID.values, df.time_delta.values),
                        "time": np.arange(pd.to_datetime(df.FROM.values), pd.to_datetime(df.TO.values), np.timedelta64(1,'s'))})
#Second - without pd.to_datetime    
x = pd.DataFrame({ "ID": np.repeat(df.ID.values, df.time_delta.values),
                        "time": np.arange(df.FROM.values, df.TO.values, np.timedelta64(1,'s'))})

此处的想法是将ID从FROM列到TO列(time_delta)重复多少秒。但我不断收到错误ValueError: Could not convert object to NumPy timedelta

这是我的dtypes的{​​{1}},

df

有人可以告诉我我在做什么错吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用:

#convert columns to timedeltas
df['FROM'] = pd.to_timedelta(df['FROM'] + ':00')
df['TO'] = pd.to_timedelta(df['TO'] + ':00')

#for each row create timedelta_range and join together
df1 = (pd.concat([pd.Series(r.ID,
                   pd.timedelta_range(r.FROM,r.TO, freq='1Min')) for r in df.itertuples()])
        .reset_index())

df1.columns = ['time','ID']
print (df1)
       time ID
0  15:30:00  A
1  15:31:00  A
2  15:32:00  A
3  15:33:00  A
4  16:40:00  B
5  16:41:00  B
6  16:42:00  B
7  16:43:00  B
8  16:44:00  B
9  15:20:00  C
10 15:21:00  C
11 15:22:00  C

this answer中的numpy解决方案更改了时间增量:

#data from linked question
print (df)
  ID   FROM     TO
0  A  15:30  15:33
1  B  16:40  16:44
2  C  15:20  15:22


#repeat constant
minute = int(60 * 1e9)

#convert both columns to timedeltas and then to numpy arrays
sd = pd.to_timedelta(df['FROM'] + ':00').values
ed = pd.to_timedelta(df['TO'] + ':00').values
dd = ed - sd
#number of repeats
ds = (dd / minute).astype(int) + 1

smins = ds.sum()
cmins = ds.cumsum()
rng = np.arange(smins)
slc = np.roll(cmins % smins, 1)
add = rng - rng[slc].repeat(ds)

#DataFrame constructor
df = pd.DataFrame(dict(
       ID = df.ID.values.repeat(ds),
       time = sd.repeat(ds) + add * minute))

print(df)
   ID     time
0   A 15:30:00
1   A 15:31:00
2   A 15:32:00
3   A 15:33:00
4   B 16:40:00
5   B 16:41:00
6   B 16:42:00
7   B 16:43:00
8   B 16:44:00
9   C 15:20:00
10  C 15:21:00
11  C 15:22:00