Pandas pdDataFrame从多列和多行数据中获取最早时间

Pandas pdDataFrame从多列和多行数据中获取最早时间,pandas,Pandas,我正在写一篇Alexa skill,告诉我下一班公共汽车什么时候能载我去上班。我已经到了一个地步,我有了一个包含必要信息的数据框架。看起来是这样的: BusStop 1st 2nd 3rd 4th 5th BusLine 10 myStop 20:05 20:16 20:28 20:38 20:52 A 3 myStop 16:07 17:07 18:13 19:12 20:12 E 15 myStop 1

我正在写一篇Alexa skill,告诉我下一班公共汽车什么时候能载我去上班。我已经到了一个地步,我有了一个包含必要信息的数据框架。看起来是这样的:

   BusStop    1st    2nd    3rd    4th    5th BusLine
10  myStop  20:05  20:16  20:28  20:38  20:52       A
3   myStop  16:07  17:07  18:13  19:12  20:12       E
15  myStop  18:26  18:36  18:46  18:58  19:25       K
但是我想把它转换成只包括最早的时间,这样Alexa就可以告诉我“A车5分钟后到,K车20分钟后到”或者类似的话

   BusStop    1st  BusLine
10  myStop  16:07   E
3   myStop  17:07   E
15  myStop  18:13   E
我有办法做到这一点,但它似乎相当笨拙,不知道是否有更好的方法来做到这一点。我让它使用以下代码:

ranked_buses_to_work = pd.DataFrame()

for i in [ '1st','2nd','3rd','4th','5th']:
    temp_df = buses_to_work_df[['BusStop', i, 'BusLine']]
    temp_df.columns = ['BusStop', 'BusTime', 'BusLine']
    ranked_buses_to_work = ranked_buses_to_work.append(temp_df)
    ranked_buses_to_work  = ranked_buses_to_work .sort_values(by=['BusTime'], inplace=True)

有更好的方法吗?

不清楚所需输出的实际逻辑是什么,但这是可行的:

在数据帧中查找3个最小值(使用numpy):

恢复最小值的索引“坐标”

idxa = np.unravel_index(idx, df.shape)
使用zip创建输出列,以友好的格式为熊猫建立索引:

df['1st'] = [df.iloc[x] for x in list(zip(idxa[0], idxa[1]))]
创建正确的“总线”列(与最小时间匹配的列)

以干净的格式显示结果

ans = df.iloc[:,[0,-1,-2]]
输出:
不清楚所需输出的实际逻辑是什么,但这是可行的:

在数据帧中查找3个最小值(使用numpy):

恢复最小值的索引“坐标”

idxa = np.unravel_index(idx, df.shape)
使用zip创建输出列,以友好的格式为熊猫建立索引:

df['1st'] = [df.iloc[x] for x in list(zip(idxa[0], idxa[1]))]
创建正确的“总线”列(与最小时间匹配的列)

以干净的格式显示结果

ans = df.iloc[:,[0,-1,-2]]
输出:
为什么A有16:07您确定您的预期输出是正确的吗?输出是正确的。16:07时的A只是一个人为错误(我编辑了第一个表以显示我想要的-当时我没有工作代码)。为什么A有16:07?您确定预期的输出是正确的吗?输出是正确的。16:07时的A只是一个人为错误(我编辑了第一个表以显示我想要的-我当时没有工作代码)。这当然是一种我不会想到的方法!谢谢这是一个相当“工匠”的方法,我相信有多种方法可以做到这一点,所以希望其他人分享他们的观点!这当然是一种我不会想到的方法!谢谢这是一个相当“工匠”的方法,我相信有多种方法可以做到这一点,所以希望其他人分享他们的观点!我想会有类似于熔化函数的东西——这就是我想要的。我想会有类似于熔化函数的东西——这就是我想要的。
import pandas as pd
from io import StringIO

# Sample data
df = pd.read_fwf(StringIO(
"""BusStop    1st    2nd    3rd    4th    5th BusLine
myStop  20:05  20:16  20:28  20:38  20:52       A
myStop  16:07  17:07  18:13  19:12  20:12       E
myStop  18:26  18:36  18:46  18:58  19:25       K
"""), index=False)


# transform the wide dataframe into a tall dataframe sorted by time
dfm = df.melt(id_vars = ["BusStop", "BusLine"], var_name = 'order', value_name="departure") \
         .sort_values('departure')

# set the currrent time and number of entries to report
# ProabblyuUse se proper date time variables instead
time_now = '16:10'
how_many = 5


# select entries > time_now and get the number wanted        
dfm[dfm.departure > time_now][['BusLine', 'departure']].head(how_many) 


#Out[156]: 
#  BusLine departure
#4       E     17:07
#7       E     18:13
#2       K     18:26
#5       K     18:36
#8       K     18:46