Pandas pdDataFrame从多列和多行数据中获取最早时间
我正在写一篇Alexa skill,告诉我下一班公共汽车什么时候能载我去上班。我已经到了一个地步,我有了一个包含必要信息的数据框架。看起来是这样的: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
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