pdDataFrame получает самое раннее время из нескольких столбцов и строк данных - PullRequest
0 голосов
/ 18 декабря 2018

Я пишу навык 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

Но я хочу преобразовать его, чтобы оно включало только самые ранние времена, чтобы Алекса могла сказать мне: «Автобус приходит через 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 голосов
/ 18 декабря 2018
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
0 голосов
/ 18 декабря 2018

Не ясно, какова действительная логика желаемого вывода, но это работает:

Найдите 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]))]

Создайте правильный столбец "BusLine" (тот, который соответствует минимальному времени)

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...