Как я могу применить функцию к каждой второй строке в серии из Pandas? - PullRequest
3 голосов
/ 02 августа 2020

У меня есть таблица только с одним столбцом. Я хочу применить функцию, которую я написал, к каждой второй строке в серии. Однако, когда я это делаю, я получаю сообщение об ошибке!

The table looks like this:        And I want to get this:
names                             names
bank account                      bank account|bank|account
1256864                           1256864
bank share                        bank share|bank|share
42,566                            42,566          
bank currency                     bank currency|bank|currency
Dollar                            Dollar
batch number                      batch number|batch|number
001444                            001444
...                                ...
                    

Вот код, который я написал:

import pandas as pd
import re


df = pd.read_table('list_a.tsv')

def sep_rows (text):
    sperated = '|'.join(re.split(r'\s+', text))
    return text+'|'+sperated

# this applies the function to ALL rows!
print(df['names'].apply(sep_rows))
# I tried to choose every other row
a = df.iloc[::2].apply(sep_rows)

print(a) # But I gen an error!

И я получаю следующее:

TypeError: expected string or bytes-like object

Ответы [ 2 ]

3 голосов
/ 02 августа 2020

Ваш подход (с re и apply) слишком сложен и медленен. Следующее выражение использует собственную Pandas векторизацию и намного более эффективно (работает примерно в 4 раза быстрее).

evens = df['names'].iloc[::2]    
evens[:] = evens + '|' + evens.str.replace('\s+', '|')
#                       names
#0  bank account|bank|account
#1                    1256864
#2      bank share|bank|share
#3                     42,566
1 голос
/ 02 августа 2020

Рассматривайте текст как серию, и тогда ваша функция должна работать:

def sep_rows(text):
    separated = text.str.replace(r"\s+", "|")
    return text + "|" + separated

df.iloc[::2].apply(sep_rows)

             names
0   bank account|bank|account
2   bank share|bank|share
4   bank currency|bank|currency
6   batch number|batch|number

Другой способ получить результат: list comprehension:

import re
df['new_column'] = ["|".join((text, re.sub(r"\s+", "|", text))) 
                    if num%2 ==0 else text 
                    for num, text in enumerate(df.names)
                   ]

df

   names                  new_column
0   bank account    bank account|bank|account
1   1256864                          1256864
2   bank share      bank share|bank|share
3   42,566                           42,566
4   bank currency   bank currency|bank|currency
5   Dollar                           Dollar
6   batch number    batch number|batch|number
7   001444                           001444
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...