在DataFrame中查找最近的时间

时间:2018-04-05 14:27:48

标签: python dataframe time

我有两个不同的时间格式数据集

df1 = pd.DataFrame( {'A': [1499503900, 1512522054, 1412525061, 1502527681, 1512532303]})

df2 = pd.DataFrame( {'B' : ['2017-12-15T11:47:58.119Z', '2017-05-31T08:27:41.943Z', '2017-06-05T14:44:56.425Z', '2017-05-30T16:24:03.175Z' , '2017-07-03T10:20:46.333Z', '2017-06-16T10:13:31.535Z' , '2017-12-15T12:26:01.347Z', '2017-06-15T16:00:41.017Z', '2017-11-28T15:25:39.016Z', '2017-08-10T08:48:01.347Z'] })

我需要找到第一个数据集中每个数据的最近日期。无所谓多远。只需要最近的时间。例如:

1499503900 for '2017-07-03T10:20:46.333Z'
1512522054 for '2017-12-15T12:26:01.347Z'
1412525061 for '2017-05-31T08:27:41.943Z'
1502527681 for '2017-08-10T08:48:01.347Z'
1512532303 for '2017-06-05T14:44:56.425Z'

这里有一些帮助: 这是为了转换为长格式日期:

def time1(date_text):
    date = datetime.datetime.strptime(date_text, "%Y-%m-%dT%H:%M:%S.%fZ") 
    return calendar.timegm(date.utctimetuple())

x = '2017-12-15T12:26:01.347Z'
print(time1(x))

out:1513340761

这是为了转换为ISO格式:

def time_covert(time):
    seconds_since_epoch = time
    DT.datetime.utcfromtimestamp(seconds_since_epoch)
    return DT.datetime.utcfromtimestamp(seconds_since_epoch).isoformat()

y = 1499503900
print(time_covert(y))

out = 2017-07-08T08:51:40

任何想法都会非常有用。 提前谢谢大家!

2 个答案:

答案 0 :(得分:2)

这是一个快速入门:

def time_covert(time):
    seconds_since_epoch = time
    return datetime.utcfromtimestamp(seconds_since_epoch)

# real time series
df2['B'] = pd.to_datetime(df2['B'])
df2.index = df2['B']
del df2['B']

for a in df1['A']:
    print( time_covert(a))
    i = np.argmin(np.abs(df2.index.to_pydatetime() - time_covert(a)))
    print(df2.iloc[i])

答案 1 :(得分:1)

我想将此作为一个算法问题,而不是特定的熊猫。我的方法是对" df2"进行排序。对于df1中的每个DateTime,对已排序的df2执行二进制搜索,以获取插入的索引。然后检查找到的索引下方和上方的索引,以获得所需的输出。

以下是上述程序的代码。

  

使用标准pandas DateTime进行简单比较

df1 = pd.DataFrame( {'A': pd.to_datetime([1499503900, 1512522054, 1412525061, 1502527681, 1512532303], unit='s')})
df2 = pd.DataFrame( {'B' : pd.to_datetime(['2017-12-15T11:47:58.119Z', '2017-05-31T08:27:41.943Z', '2017-06-05T14:44:56.425Z', '2017-05-30T16:24:03.175Z' , '2017-07-03T10:20:46.333Z', '2017-06-16T10:13:31.535Z' , '2017-12-15T12:26:01.347Z', '2017-06-15T16:00:41.017Z', '2017-11-28T15:25:39.016Z', '2017-08-10T08:48:01.347Z']) })
  

根据日期对df2进行排序,并使用二进制搜索获取插入位置

df2 = df2.sort_values('B').reset_index(drop=True)
ind = df2['B'].searchsorted(df1['A'])
  

现在检查正好在插入位置上方和下方的索引之间的最小差异

for index, row in df1.iterrows():
    i = ind[index]
    if i not in df2.index:
        print(df2.iloc[i-1]['B'])
    elif i-1 not in df2.index:
        print(df2.iloc[i]['B'])
    else:
        if abs(df2.iloc[i]['B'] - row['A']) > abs(df2.iloc[i-1]['B'] - row['A']):
            print(df2.iloc[i-1]['B'])
        else:
            print(df2.iloc[i]['B'])

对于df1中的每个值,测试输出分别为这些。 (注意:请重新检查问题中给出的输出,它们与最小差异不对应)

2017-07-03 10:20:46.333000
2017-11-28 15:25:39.016000
2017-05-30 16:24:03.175000
2017-08-10 08:48:01.347000
2017-11-28 15:25:39.016000

上述过程的时间复杂度为O(NlogN),用于排序,O(logN) (N = len(df2))用于查找每个输出。如果" df1"的大小这是一个相当快的方法。