Как разделить столбец, содержащий int и строковые значения, разделенные точкой с запятой - PullRequest
0 голосов
/ 02 октября 2019

У меня есть столбец, похожий на этот:

Column0
5,00; Today is a good day
3,00; Hello there
8,00; nan
2,00; What a great weather
4,00; nan
2,00; nan

dtypes: object

Как мне разделить этот столбец на два отдельных столбца? Я хочу, чтобы это выглядело так:

Column1    Column2
5,00       Today is a good day
3,00       Hello there
8,00     
2,00       What a great weather
4,00
2,00

Я пробовал использовать:

df['Column1']=df.Column0.str.split(';').str[0]
df['Column2']=df.Column0.str.split(';').str[-1]

Но это возвращает меня к следующему:

Column1    Column2
5,00       Today is a good day
3,00       Hello there
8,00       8,00
2,00       What a great weather
4,00       4,00
2,00       2,00

Спасибо за вашу помощь! :)

Привет всем! В итоге я использовал:

df['Column2']=df['Column0'].apply(lambda x: str(x).split(';')[1] if len(str(x).split(';'))>1 else "")
df['Column1']=df.Column0.str.split(';').str[0]
df = df.drop('Column0', axis=1)

Первая строка дает мне строковые значения в столбце без NULL или NaN. Вторая строка дает мне числа

После этого я уронил Column0, потому что ябольше не нужно. Большое спасибо всем!

Column1    Column2
5,00       Today is a good day
3,00       Hello there
8,00     
2,00       What a great weather
4,00
2,00

Ответы [ 3 ]

0 голосов
/ 02 октября 2019

Вы можете присоединиться ко всему после первой точки с запятой, как это. Я предполагаю, что df.Column0.str является строкой. Если после точки с запятой ничего нет, это будет просто пустая строка.

 df['Column1']=df.Column0.str.split(';')[0]
 df['Column2']="".join(df.Column0.str.split(';')[1:])
0 голосов
/ 02 октября 2019

Причина в том, что некоторые строки содержат только одно значение. Например, строка

5,00; Today is a good day

будет разбита на

['5,00', 'Today is a good day']

, а строка

8,00; nan

будет разбита на

['8,00']

Когда вы получаете доступ к результату, используя [-1] в качестве индекса, вам будет предложено указать последнее значение из списка. Что, если вы посмотрите на приведенный выше пример, даст вам иногда число, а иногда и текст, в зависимости от того, был ли текст пустым или нет.

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

def extractor(index):
    def extract(column):
        values = column.split(';')
        if index == 0:
            return values[0]
        if len(values) < 2:
            return ''  # The default value (could also be injected via the extractor function)
        return values[1]
    return extract

df['Column1'] = df.Column0.apply(extractor(0))
df['Column2'] = df.Column0.apply(extractor(1))

Альтернативная реализация

Следующая реализация немного более явна и должна быть более удобной для сопровождения. Вместо использования split он использует partition, который лучше подходит для этого варианта использования и позволяет писать код с меньшим «индексным доступом».

Кроме того, вместо того, чтобы передавать индекс в экстрактор, я решилпередать строковое значение (может быть улучшено с помощью Enum, но это может быть излишним). Преимущество использования текста в том, что код становится более выразительным, и вам не нужно помнить, что «0» - это числовое значение, а «1» - это метка.

В целом это должно улучшить читаемость (и как таковое сопровождение) кода с минимальными изменениями.

def extractor(field):
    def extract(column):
        value, _, text = column.partition(';')
        if field == 'text':
            return text
        if field == 'value':
            return value
        raise ValueError('Unknown Field: %r' % field)
    return extract

df['Column1'] = df.Column0.apply(extractor('text'))
df['Column2'] = df.Column0.apply(extractor('value'))
0 голосов
/ 02 октября 2019

попробуй

df['Column2']=df['Column0'].apply(lambda x: str(x).split(';')[1] if len(str(x).split(';'))>1 else None)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...