Поэлементные вычисления в Pandas кадре данных - PullRequest
0 голосов
/ 05 марта 2020

У меня есть то, что, я уверен, является фундаментальным недостатком понимания того, как работают кадры данных в Python. Я уверен, что это простой вопрос, но я искал везде и не могу найти хорошего объяснения. Я пытаюсь понять, почему иногда кажется, что расчеты для фреймов данных выполняются построчно (или от ячейки к ячейке), а иногда - для всего столбца ... Например:

data = {'Name':['49-037-23094', '49-029-21476', '49-029-20812', '49-041-21318'], 'Depth':[20, 21, 7, 18]} 
df = pd.DataFrame(data) 
df

Что дает:

           Name  Depth
0  49-037-23094     20
1  49-029-21476     21
2  49-029-20812      7
3  49-041-21318     18

Теперь я знаю, что могу сделать:

df['DepthDouble']=df['Depth']*2

И получить:

           Name  Depth  DepthDouble
0  49-037-23094     20           40
1  49-029-21476     21           42
2  49-029-20812      7           14
3  49-041-21318     18           36

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

df['newName']=''.join(re.findall('\d',str(df['Name'])))

, что дает:

           Name  Depth  DepthDouble  \
0  49-037-23094     20           40   
1  49-029-21476     21           42   
2  49-029-20812      7           14   
3  49-041-21318     18           36   

                                        newName  
0  04903723094149029214762490292081234904121318  
1  04903723094149029214762490292081234904121318  
2  04903723094149029214762490292081234904121318  
3  04903723094149029214762490292081234904121318  

Таким образом, он принимает все значения в моем столбце имени, удаляя тире, и объединяя их. Конечно, я просто хотел бы, чтобы это был новый столбец имени, точно такой же, как исходный столбец «Имя», но без черточек.

Итак, кто-нибудь может помочь мне понять, что я здесь делаю неправильно? Я не понимаю, почему иногда вычисления в Dataframe для одного столбца выполняются строка за строкой (например, столбец с удвоенной глубиной), а иногда Python, кажется, принимает все значения во всем столбце и выполняет вычисления (например, столбец newName) ,

Конечно, чтобы обойти это, нужно сделать al oop для каждого индекса в df, чтобы заставить его запускаться индивидуально для каждой строки для данного столбца?

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Проблема в том, что с str(df['Name']) вы конвертируете весь Name -колонку вашего DataFrame в одну строку. Вместо этого вы хотите использовать один из pandas 'собственных методов для строк, который будет применяться к каждому отдельному элементу столбца.

Например, вы можете использовать pandas' replace метод для строк:

import pandas as pd
data = {'Name':['49-037-23094', '49-029-21476', '49-029-20812', '49-041-21318'],    'Depth':[20, 21, 7, 18]} 
df = pd.DataFrame(data) 

df['newName'] = df['Name'].str.replace('-', '')
0 голосов
/ 05 марта 2020

Если вывод, который вы ищете:

Name    Depth   newName
0   49-037-23094    20  4903723094
1   49-029-21476    21  4902921476
2   49-029-20812    7   4902920812
3   49-041-21318    18  4904121318

Способ получить это:

df['newName']=df['Name'].map(lambda name: ''.join(re.findall('\d', name)))

map, как apply, но специально для серии объекты. Поскольку вы подаете заявку только на столбец «Имя», вы работаете с серией.

Если лямбда-часть сбивает с толку, эквивалентный способ ее записи:

def find_digits(name):
    return ''.join(re.findall('\d', name))

df['newName']=df['Name'].map(find_digits)

Эквивалентная операция в традиционном цикле for:

newNameSeries = pd.Series(name='newName')
for name in df['Name']:
    newNameSeries = newNameSeries.append(pd.Series(''.join(re.findall('\d', name))), ignore_index=True)

pd.concat([df, newNameSeries], axis=1).rename(columns={0:'newName'})

Пока может быть, немного более чистый способ сделать l oop, вы можете увидеть, насколько проще первый подход по сравнению с попыткой использовать циклы for. Это также быстрее. Как вы уже указали, вы знаете, избегайте циклов при использовании pandas.

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