timedelta к строковому типу в панде - PullRequest
0 голосов
/ 29 июня 2018

У меня есть фрейм данных df, а его первый столбец - timedelta64

df.info():

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 686 entries, 0 to 685
Data columns (total 6 columns):
0    686 non-null timedelta64[ns]
1    686 non-null object
2    686 non-null object
3    686 non-null object
4    686 non-null object
5    686 non-null object

Если я print(df[0][2]), например, это даст мне 0 days 05:01:11. Однако я не хочу подавать 0 days. Я только хочу, чтобы 05:01:11 был напечатан. Может ли кто-нибудь научить меня, как это сделать? Большое спасибо!

Ответы [ 3 ]

0 голосов
/ 29 июня 2018

Учитывая, что OP подходит для столбца объекта (немного многословно):

def splitter(td):

  td = str(td).split(' ')[-1:][0]

  return td


df['split'] = df['timediff'].apply(splitter)

В основном мы берем столбец timedelta, преобразуем содержимое в строку, затем разделяем строку (создаем список) и берем последний элемент этого списка, который будет компонентом hh: mm: ss.

Обратите внимание, что указание ' ' для того, на что делить, здесь избыточно.

Альтернативный вкладыш:

df['split2'] = df['timediff'].astype('str').str.split().str[-1]

что очень похоже, но не очень симпатично ИМХО. Кроме того, вывод включает в себя миллисекунды, что не имеет место в первом решении. Я не уверен, что причина этого (пожалуйста, прокомментируйте, если вы делаете). Если ваши данные велики, возможно, стоит попробовать эти разные подходы.

0 голосов
/ 12 октября 2018

Вот короткая и надежная версия с использованием apply():

df['timediff_string'] = df['timediff'].apply(
    lambda x: f'{x.components.hours:02d}:{x.components.minutes:02d}:{x.components.seconds:02d}'
              if not pd.isnull(x) else ''
)

Используется атрибут компоненты для объектов Timedelta панд, а также обрабатывается пустые значения (NaT).

Если столбец timediff не содержит объектов Timedelta панд, вы можете преобразовать его:

df['timediff'] = pd.to_timedelta(df['timediff'])
0 голосов
/ 29 июня 2018

Возможно по:

df['duration1'] = df['duration'].astype(str).str[-18:-10]

Но решение не является общим, если ввод 3 days 05:01:11, он также удаляет 3 days.

Таким образом, решение работает только на время, меньше одного дня.

Более общим решением является создание собственного формата :

N = 10
np.random.seed(11230)
rng = pd.date_range('2017-04-03 15:30:00', periods=N, freq='13.5H')
df = pd.DataFrame({'duration': np.abs(np.random.choice(rng, size=N) - 
                                 np.random.choice(rng, size=N)) })  

df['duration1'] = df['duration'].astype(str).str[-18:-10]

def f(x):
    ts = x.total_seconds()
    hours, remainder = divmod(ts, 3600)
    minutes, seconds = divmod(remainder, 60)
    return ('{}:{:02d}:{:02d}').format(int(hours), int(minutes), int(seconds)) 

df['duration2'] = df['duration'].apply(f)
print (df)

         duration duration1  duration2
0 2 days 06:00:00  06:00:00   54:00:00
1 2 days 19:30:00  19:30:00   67:30:00
2 1 days 03:00:00  03:00:00   27:00:00
3 0 days 00:00:00  00:00:00    0:00:00
4 4 days 12:00:00  12:00:00  108:00:00
5 1 days 03:00:00  03:00:00   27:00:00
6 0 days 13:30:00  13:30:00   13:30:00
7 1 days 16:30:00  16:30:00   40:30:00
8 0 days 00:00:00  00:00:00    0:00:00
9 1 days 16:30:00  16:30:00   40:30:00
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...