2017-02-20 4 views
1

У меня есть следующие панд dataframe:Как заменить только одиночные числа на другое число в рамке данных pandas?

date 
0 1 
1 2 
2 23 
3 31 
4 4 
... 
n 3 

Как я могу только заменить все числа от 1 до 9 (например чисел с одной цифрой) в следующем формате:

01, 02, 03, 04, 05, 06, 07, 08, 09 

Я попытался использовать функцию замены панды следующим образом:

df['date'] = df['date'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9']), 
                  [' 01 ', ' 02 ', ' 03 ', '04 ', ' 05 ', ' 06 ', ' 07 ', ' 08 ', ' 09 '],regex=True) 

Однако это не сработало, потому что оно изменяет все (т. цифры с более чем одной цифрой) числа внутри фрейма данных. Таким образом, как я могу нормализовать столбец даты ?.

ответ

3

При необходимости бросить столбец str с помощью astype(str), затем вызовите str.zfill к 0 подушечка эти цифры:

In [13]: 
df['date'] = df['date'].astype(str).str.zfill(2) 
df 

Out[13]: 
    date 
0 01 
1 02 
2 23 
3 31 
4 04 

относительно вашего комментария:

In [17]: 
df['year'] = '20' + df['date'] 
df 

Out[17]: 
    date year 
0 01 2001 
1 02 2002 
2 23 2023 
3 31 2031 
4 04 2004 

вышеуказанных работ, когда колонна DTYPE уже str

+0

Спасибо, я не знал, что это можно было сделать ... это решение в порядке. Однако, как насчет того, если у меня будет такая же проблема в течение многих лет ?. Например, рассмотрим столбцы с 23, 12, 15 и т. Д. Затем мне нужно ввести 20 с левой стороны цифры ... Как я могу это сделать? – tumbleweed

+0

Если уже str, вы можете просто сделать «20» + df ['year'] 'или' '20' + df ['year']. Astype (str) ' – EdChum

+0

Не могли бы вы привести пример? ... Спасибо за помощь! – tumbleweed

1

Попробуйте ^([0-9])$ для шаблона и 0\1 для замены:

>>> df = p.DataFrame(data={'date': ['1', '2', '12', '31']}) 
>>> df['date'].replace('^([0-9])$', r'0\1', regex=True) 

0 01 
1 02 
2 12 
3 31 
Name: date, dtype: object 

Читая комментарии, которые вы написали по другим вопросам, кажется, что вы делаете форматирование даты. Я считаю, что для этого лучше использовать datetime. Вот пример:

>>> from datetime import datetime 
>>> df = p.DataFrame(data={'date': ['1', '2', '12', '31'], 'month': ['1', '2', '5', '12'], 'year': ['07', '10', '16', '17']}) 
>>> dates = df.apply(lambda row: datetime(year=2000+int(row['year']), month=int(row['month']), day=int(row['date'])), axis=1) 
>>> dates 

0 2007-01-01 
1 2010-02-02 
2 2016-05-12 
3 2017-12-31 
dtype: datetime64[ns] 
>>> dates.apply(lambda row: row.strftime('%x')) 

0 01/01/07 
1 02/02/10 
2 05/12/16 
3 12/31/17 
dtype: object 
>>> dates.apply(lambda row: row.strftime('%Y-%m-%d')) 

0 2007-01-01 
1 2010-02-02 
2 2016-05-12 
3 2017-12-31 
dtype: object 

Таким образом, вы получаете лучший контроль над форматом даты.

Редактировать

Если вам нужно еще больше контроля над преобразованием, сделать функцию вместо:

>>> def convert_dates(row): 
...  year = row['year'] 
...  month = row['month'] 
...  day = row['date'] 
...  if '' in [year, month, day]: 
...   return None # Don't bother with empty values 
...  year, month, day = [int(x) for x in [year, month, day]] 
...  if year < 100: 
...   year += 2000 
...  return datetime(year, month, day) 
... 
>>> df = p.DataFrame(data={'date': ['11', '2', '1', '31'], 'month': ['08', '2', '5', '12'], 'year': ['1985', '10', '16', '']}) 
>>> df.apply(convert_dates, axis=1) 

0 1985-08-11 
1 2010-02-02 
2 2016-05-01 
3   NaT 
dtype: datetime64[ns] 
+0

в рамке данных панды ?. – tumbleweed

+1

Да, как и ваш код, но с другим шаблоном. Я добавил пример. –

+0

Я обновил этот ответ, чтобы использовать 'apply' для создания фактического объекта' datetime' вместо этого для упрощения форматирования. –

1

Использование границы слов:

Поиск: \b(\d)\b
Заменить: 0$1

1

Использование регулярное выражение, что-то вроде

p = re.compile(r'\b\d\b') 
p.sub(lambda x: '0'+x.group(), '0 1 2 23 34 5') 
## result: '00 01 02 23 34 05'