Панды разделены после месяца дневного времени от остальной части последовательности - PullRequest
5 голосов
/ 25 октября 2019

Я работаю с фреймом данных панд. Я пытаюсь разделить столбец после даты и времени от остальной части строки.

df
   data
0  Oct 22 12:56:52 server1
1  Oct 22 12:56:52 server2
2  Oct 22 12:56:53 server2
3  Oct 22 12:56:54 server2
4  Oct 22 12:56:56 comp2

Желаемый результат:

df
   date              machine
0  Oct 22 12:56:52   server1
1  Oct 22 12:56:52   server2
2  Oct 22 12:56:53   server2
3  Oct 22 12:56:54   server2
4  Oct 22 12:56:56   comp2

Если я пытаюсь что-то вроде df["data"].str.extract('^(.*? [0-9]{2}) (.*)$'), это простоснимает все после 22 (дня)

Ответы [ 5 ]

5 голосов
/ 25 октября 2019

Вы также можете передать точную форму даты \ времени:

df['data'].str.extract('(\w* \d* \d*:\d*:\d*) (.*)')

, вывод:

                 0        1
0  Oct 22 12:56:52  server1
1  Oct 22 12:56:52  server2
2  Oct 22 12:56:53  server2
3  Oct 22 12:56:54  server2
4  Oct 22 12:56:56    comp2
4 голосов
/ 25 октября 2019

Использование positive lookbehind для разделения на {semicolon}{two numbers}{space}:

Подробности:

  • (?<=) является положительным взглядом сзади (проверьте, находится ли что-нибудь перед строкой)
  • :\d{2} - это шаблон: {semicolon}{two numbers}
  • \s - это пробел

Вывод : мы разбиваем на whitespace, но только еслиему предшествует шаблон, описанный выше.

s = df['data'].str.split('(?<=:\d{2})\s')

df['date'] = s.str[0]
df['machine'] = s.str[1]
df = df.drop(columns='data')

Или как piRSquared & jezrael предложить в комментариях , в одну строку:

df['date'], df['machine'] = zip(*df.pop('data').str.split('(?<=:\d{2})\s'))

Выход

              date  machine
0  Oct 22 12:56:52  server1
1  Oct 22 12:56:52  server2
2  Oct 22 12:56:53  server2
3  Oct 22 12:56:54  server2
4  Oct 22 12:56:56    comp2
3 голосов
/ 25 октября 2019

понимание

Это зависит от того, что формат данных всегда равен 15 символам.
Кроме того, поскольку нам все равно придется отбрасывать столбец 'data', я подумал, что было бы лучше простосоздать фрейм данных с нуля.

pd.DataFrame([[s[:15], s[16:]] for s in df.data], columns=['date', 'machine'])

              date  machine
0  Oct 22 12:56:52  server1
1  Oct 22 12:56:52  server2
2  Oct 22 12:56:53  server2
3  Oct 22 12:56:54  server2
4  Oct 22 12:56:56    comp2

rsplit

Зависит от 'machine' имя, не имеющее пробелов.

Это работает, потому что обеспечен доступ к строкеpandas.Series.str является итеративным и может использоваться в операторе присваивания, аналогичном x, y = (1, 2)

Также обратите внимание, что я непростительно воспринял идею использовать pop в этом случае из @ jezrael

df['date'], df['machine'] = df.pop('data').str.rsplit(n=1).str

df

              date  machine
0  Oct 22 12:56:52  server1
1  Oct 22 12:56:52  server2
2  Oct 22 12:56:53  server2
3  Oct 22 12:56:54  server2
4  Oct 22 12:56:56    comp2
2 голосов
/ 25 октября 2019

Если формат остается прежним:

df['date'] = df['data'].str[:-8]
df['machine'] = df['data'].str[-8:]

print(df)

                      data             date   machine
0  Oct 22 12:56:52 server1  Oct 22 12:56:52   server1
1  Oct 22 12:56:52 server2  Oct 22 12:56:52   server2
1 голос
/ 25 октября 2019

Попробуйте это:

r"(?<=[\S ][\d]{2}:[\d]{2}:[\d]{2} )[\S ]+"

Я не лучший в регулярных выражениях, безусловно, есть лучший подход, но это работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...