Панды: объедините разные CSV в один df, объединяя по названию

#python #pandas #concatenation

Вопрос:

У меня есть несколько разных csv-файлов в одной папке с такой структурой:

CSV 1:

     Name      Passes     Shots
1   Player 1     20        5
2   Player 2     30        6
3   Player 3     10        3
 

CSV 2:

     Name      Goals     Duels
1   Player 3     2        3
2   Player 1     0        2
3   Player 2     1        7
 

CSV 3:

     Name      Country     Age
1   Player 2     SPA        25
2   Player 3     SPA        26
3   Player 1     USA        23
 

Я хотел бы объединить эти CSV в одном фрейме данных с пандами, и результат, который я хочу, будет:

      Name    Passes     Shots    Goals    Duels    Country    Age
1   Player 1     20        5       0        2        USA       23
2   Player 2     30        6       1        7        SPA       25
3   Player 3     10        3       2        3        SPA       26
 

Я пытаюсь объединить их с помощью этого кода, но я получаю фрейм данных с 9 строками (Игрок 1 3 раза, Игрок 2 3 раза и игрок 3 3 раза).:

 file_extension = ".csv"

all_filenames = [i for i in glob.glob(f"*{file_extension}")]

df = pd.concat([pd.read_csv(file) for file in all_filenames])
 

В результате я получаю что-то вроде:

      Name    Passes     Shots    Goals    Duels    Country    Age
1   Player 1     20        5      NaN      NaN       NaN      NaN
2   Player 2     30        6      NaN      NaN       NaN      NaN
3   Player 3     10        3      NaN      NaN       NaN      NaN
1   Player 1    NaN      NaN       0        2        NaN      NaN
2   Player 2    NaN      NaN       1        7        NaN      NaN
3   Player 3    NaN      NaN       2        3        NaN      NaN
1   Player 1    NaN      NaN       NaN      NaN      USA       23
2   Player 2    NaN      NaN       NaN      NaN      SPA       25
3   Player 3    NaN      NaN       NaN      NaN      SPA       26
 

Есть идеи о том, как объединить их так, как я хочу, с именем в качестве ссылки? Заранее спасибо!

Ответ №1:

Используйте слияние панд и укажите левую и правую клавиши

 df1 = pd.DataFrame({
    'Name': ['Player 1', 'Player 2', 'Player 3'],
    'Passes': [20, 30, 10],
    'Shots': [5, 6, 3]
})
df2 = pd.DataFrame({
    'Name': ['Player 3', 'Player 1', 'Player 2'],
    'Goals': [2, 0, 1],
    'Duels': [3, 2, 7]
})
df3 = pd.DataFrame({
    'Name': ['Player 2', 'Player 3', 'Player 1'],
    'Country': ['SPA', 'SPA', 'USA'],
    'Age': [25, 26, 23]
})

df1.merge(df2, left_on="Name", right_on="Name").merge(
    df3, left_on="Name", right_on="Name")
 

Выход:

         Name    Passes  Shots   Goals   Duels   Country Age
0   Player 1        20     5    0          2    USA     23
1   Player 2        30     6    1          7    SPA     25
2   Player 3        10     3    2          3    SPA     26
 

Правка 1:

Если у вас много таких файлов, и все они имеют Name ключ as, вы можете использовать:

 df = None
for f in list_of_files:
  df = pd.read_csv(f) if df is None else df.merge(
      pd.read_csv(f), left_on="Name", right_on="Name")
 

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

1. Спасибо за ваши ответы. У меня много резюме (более 50)… должен ли я читать один за другим в разных dfs, а затем объединять? Разве нет решения для чтения и объединения одновременно?

2. Я пробовал, но, к сожалению, он показывает пустой фрейм данных со всеми столбцами, кроме 0 строк

3. Убедитесь, что все ваши столбцы «Имя» правильные

4. Я проверил, и у всех у них есть столбец с именем. df по-прежнему пуст, со всеми столбцами, но без строк

Ответ №2:

Способ обойти drop_duplicates-это просто объединить несколько заголовков столбцов. Таким образом, если есть игрок, который играл в двух разных командах, имя игрока будет одинаковым, но команда будет другой, и слияние распознает это.

Вы также можете использовать pandas для чтения в формате CSV во фрейм данных (поскольку вам нужно много читать, это может быть большой цикл).

 data1 = pd.read_csv(PATH_TO_CSV = '/your_csv.csv')
data2 = pd.read_csv(PATH_TO_CSV = '/your_second_csv.csv')

merged_df = pd.merge(data1, data2, how='outer', on=['player', 'team']
 

Что еще следует отметить при работе с фреймами данных, так это то, что вы можете объединить их вместе на оси, чтобы объединить их вместе. Это может выглядеть примерно так…

 df_list = []
for loop {
   data = pd.read_csv(PATH_TO_CSV = '/your_csv.csv')
   # check type of data to make sure its a dataframe
   df_list.append(data)
   # and on to the next csv
}
# after the for loop you can concatenate the data frames together
concat_df = pd.concat(df_list, axis=0, sort=False)
# need to make sure the first df_list is iterable or else you will get an error
# then you can create a new csv with all of your data
concat_df.to_csv(OUTPUT_PATH   '/your_new_csv.csv', index=False)