pandas: разделение значений и объединение по столбцам

#python #pandas

#python #pandas

Вопрос:

У меня есть csv-файл с некоторыми пользовательскими данными, который по той или иной причине разделил имя электронной почты и домен электронной почты на два отдельных столбца. У некоторых пользователей также есть несколько электронных писем. Я хотел бы объединить их в одно электронное письмо или один список, если позволяет случай.

пример:

 emailname                          | emaildomain
john.smith; smithj                 | gmail.com, biz.net
sample.name                        | aol.com
 

Я хотел бы изменить это на:

 email
[john.smith@gmail.com, smithj@biz.net]
[sample.name@aol.com] 
 

оттуда он будет отправлен в словарь, где мне придется перебирать каждое значение в ячейке и делать запись из них, что я примерно представляю, как сделать, просто используя базовый python или следуя аналогичной логике.

Я смог разделить каждое поле на список, используя df['email name'] = df['email name'].str.split(';') который, я получил список для каждого значения в поле. Тем не менее, я застрял в том, как я бы объединил их в одно поле.

В чистом python я бы сделал что-то вроде:

 emaillist = []
for i in emailname: #where the assumption is there is a 1:1 relationship between each name and domain
    e = '@'.join(emailname[i],emaildomain[i])
    emaillist.append(e)
 

но в pandas я не уверен, как получить индекс списка внутри ячейки фрейма данных. В идеале я также хотел бы пропустить любые пустые строки, но если просто создать «пустой» список типа: [@] тогда все в порядке, я могу исправить это позже.

Ответ №1:

Используйте понимание вложенных списков с * помощью для распаковки списков:

 L = [['@'.join(z) for z in zip(*[y.split(',') for y in x])] 
                  for x in zip(df['emailname'],df['emaildomain'])]
print (L)
[['john.smith@gmail.com', 'smithj@biz.net'], ['sample.name@aol.com']]
 

Комментарии:

1. Хм. Итак, я попробовал это, и я получаю AttributeError: 'list object has no attribute 'split' . Я переделал это, еще не разделив ячейки с несколькими значениями, и он соединил их неправильно, ['john.smith;smithj@gmail.com;biz.net]' . Я попытался переместить .split(';') во 2-ю строку понимания, и это также выдает ошибку: AttributeError: Can only use .str accessor with string values!

2. @noscodemos — Возможны ли некоторые неправильные значения? Если использовать df = df.dropna() перед моим решением, оно работает?

3. Есть несколько пустых значений, но теоретически это должно просто создать список со значением [@] . Выполнение a dropna() не имело никакого эффекта.

4. @noscodemos Вы можете протестировать одну идею 0 L = [['@'.join(z) for z in zip(*[y.split(',') for y in x])] for x in zip(df['emailname'].astype(str),df['emaildomain'].astype(str))] ?

Ответ №2:

Ну, вы можете попробовать это. Это создаст новый столбец электронной почты с желаемым результатом

 final_email = []
for i,k in enumerate(zip(list(df['Emailname'].values), list(df['Emaildomain'].values))):
  name,domain = k
  a = []
  for ij, val in enumerate(name.split(';')):
    val = val '@' str(domain.split(',')[ij]).strip()
    a.append(val)
  final_email.append(a)
df['Email'] = final_email
df
 

Комментарии:

1. Я продолжаю получать list index out of range сообщение об ошибке.

2. Вы применяете это ко всему вашему набору данных?

3. только эти два столбца, но полностью вниз, да.

4. все ваши значения emalname и emaildomain должны быть в той же форме, что вы указали в вопросе, иначе это может привести к ошибке. Просто представьте свои данные такими john.smith, smithj , а john.smith; smithj не . Изменение с ; на ‘,’ может привести к ошибке. Это зависит от вашего набора данных

5. Хорошо, тогда вы можете найти, какая строка вызывает ошибку? Вы можете разделить фрейм данных на множество небольших фреймов данных и проверять приведенный выше код в этих фреймах данных, пока не получите небольшой фрейм данных, который вызывает ошибку.