Применить в пандах в зависимости от ряда не работает - PullRequest
1 голос
/ 31 мая 2019

У меня есть датафрейм с именами покупателя и помощника:

df = pd.DataFrame([
{ 'buyer': 'Lebron James', 'assistant': 'Lebron James' },
{ 'buyer': 'Jon Snow', 'assistant': 'Arya Stark' },
{ 'buyer': 'Frodo Baggins', 'assistant': 'Sam Gamyi' }
])

Я хотел бы разделить имена покупателей на их имена и фамилии, поэтому ожидаемый результат будет:

first_name surname Lebron James Jon Snow Frodo Baggings

Для этого я определил функцию и попытался использовать apply ():

def first_name(row):
    return df['buyer'][row].split()[0]

df['first_name'] = df.apply(first_name, axis = 1)

Однако я получаю следующую ошибку:

    Traceback (most recent call last):

  File "<ipython-input-35-f3bcdf3bb991>", line 1, in <module>
    df.apply(first_name, axis = 1)

  File "/Users/javier.lopez/anaconda3/lib/python3.7/site-packages/pandas/core/frame.py", line 6487, in apply
    return op.get_result()

  File "/Users/javier.lopez/anaconda3/lib/python3.7/site-packages/pandas/core/apply.py", line 151, in get_result
    return self.apply_standard()

  File "/Users/javier.lopez/anaconda3/lib/python3.7/site-packages/pandas/core/apply.py", line 257, in apply_standard
    self.apply_series_generator()

  File "/Users/javier.lopez/anaconda3/lib/python3.7/site-packages/pandas/core/apply.py", line 286, in apply_series_generator
    results[i] = self.f(v)

  File "<ipython-input-32-410cb25f2482>", line 2, in first_name
    return df['buyer'][row].split()[0]

  File "/Users/javier.lopez/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py", line 5067, in __getattr__
    return object.__getattribute__(self, name)

AttributeError: ("'Series' object has no attribute 'split'", 'occurred at index 0')

Я понял, что использование apply with axis = 1 послало номер строки в качестве аргумента, поэтому я не понимаю, почему он не работает. Если я вручную поставлю номер строки в качестве аргумента, он будет работать как положено:

first_name(1)

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Использование Series.str.split:

df1 = df['buyer'].str.split(expand=True).rename(columns={0:'first_name',1:"surname"})

print(df1)
  first_name  surname
0     Lebron    James
1        Jon     Snow
2      Frodo  Baggins

или:

df = df.join(df1)

print(df)
      assistant          buyer first_name  surname
0  Lebron James   Lebron James     Lebron    James
1    Arya Stark       Jon Snow        Jon     Snow
2     Sam Gamyi  Frodo Baggins      Frodo  Baggins
1 голос
/ 31 мая 2019

Чтобы ответить на ваш вопрос, вы можете использовать:

def first_name(x):
    return x.split()[0]
df['first']=df.buyer.apply(first_name)
print(df)

      assistant          buyer   first
0  Lebron James   Lebron James  Lebron
1    Arya Stark       Jon Snow     Jon
2     Sam Gamyi  Frodo Baggins   Frodo

Однако, как указал @Sandeep, вы также должны рассматривать встроенные решения для панд как series.str.split(), столбец можно напрямую назначить с помощью df.assign()

df=df.assign(first=df.buyer.str.split().str[0])

      assistant          buyer   first
0  Lebron James   Lebron James  Lebron
1    Arya Stark       Jon Snow     Jon
2     Sam Gamyi  Frodo Baggins   Frodo
...