我正在写一种Alexa技能来告诉我下一班公共汽车什么时候带我去上班。我已经有了一个包含必要信息的熊猫数据框。看起来像这样:
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)
有更好的方法吗?
答案 0 :(得分:2)
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
答案 1 :(得分:1)
不清楚所需输出的实际逻辑是什么,但这可行:
在数据框中找到3个最小值(使用numpy):
import numpy as np
idx = df.values.ravel().argsort()[:3]
恢复最小值的索引“坐标”
idxa = np.unravel_index(idx, df.shape)
使用zip创建输出列,以友好的格式为熊猫建立索引:
df['1st'] = [df.iloc[x] for x in list(zip(idxa[0], idxa[1]))]
创建正确的“公交线路”列(与最短时间匹配的那一列)
df['BusLine'] = [df.iloc[x,-2] for x in idxa[0]]
以干净的格式显示结果
ans = df.iloc[:,[0,-1,-2]]
BusStop 1st BusLine
10 myStop 16:07 E
3 myStop 17:07 E
15 myStop 18:13 E