pdDataFrame最早出现在多列和多行数据中

时间:2018-12-17 21:45:46

标签: pandas

我正在写一种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)

有更好的方法吗?

2 个答案:

答案 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