Объединить все файлы листов и создать один новый столбец с именами листов в Python

#python #python-3.x #pandas #dataframe #xlrd

#python #python-3.x #pandas #фрейм данных #xlrd

Вопрос:

Учитывая файл Excel test.xlsx который имеет много листов: 1.DC , 2.SH и 3.GZ , и т.д.

 import xlrd
dfs = xlrd.open_workbook('./test.xlsx', on_demand = True)
print(dfs.sheet_names()) 
  

Out:

 ['1.DC', '2.SH', '3.GZ']
  

Как я мог прочитать и объединить все листы и создать новый столбец с именами листов, удалив 1., 2., 3., etc. в начальной части имена каждого листа?

Ожидаемый результат будет таким:

введите описание изображения здесь

Ответ №1:

Используйте read_excel with sheet_name=None для преобразования всех листов в DataFrame s:

 dfs = pd.read_excel('test.xlsx', sheet_name=None)

dfs = {k: v.loc[:, ~v.columns.str.contains('Unnamed')] for k, v in dfs.items()}

# print(dfs) 
  

Затем, если вам нужен один столбец, используйте сопоставление lsit с выберите этот столбец, здесь name

 df = pd.DataFrame([(x, k) for k, v in dfs.items() for x in v['name']], 
                  columns=['name','city'])
df['city'] = df['city'].str.replace('^[0-9.] ', '')
print (df)
      name    city
0    James      DC
1     Bond      DC
2   Steven      DC
3   Walker      SH
4      Tom      SH
5   Filler      GZ
6   Cooker      GZ
7      Tim      GZ
  

Или, если нужно, все столбцы опустить [name] здесь:

 dfs = pd.read_excel('test.xlsx', sheet_name=None)
print(dfs) 

df = (pd.concat(dfs)
        .reset_index(level=1, drop=True)
        .rename_axis('city')['name']
        .reset_index())
df['city'] = df['city'].str.replace('^[0-9.] ', '')
print (df)
      city    name
0       DC   James
1       DC    Bond
2       DC  Steven
3       SH  Walker
4       SH     Tom
5       GZ  Filler
6       GZ  Cooker
7       GZ     Tim
  

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

1. Спасибо, есть ли способ игнорировать Unnamed columns , когда я читаю данные? Я нахожу, что на каждом листе много: Unnamed: 1 Unnamed: 2 ..., etc.

2. @ahbon — хммм, как выглядят реальные имена столбцов? Все есть unamed ?

3. Кроме name каждого листа, есть и другие столбцы Unnamed: 1 Unnamed: 2 ... Unnamed: 58 Unnamed: 59 Unnamed: 60 .

4. @ahbon — я понял, добавьте второй вариант кода dfs= {k: v.loc[:, ~v.columns.str.contains('Unnamed')] for k, v in dfs.items()} , отфильтруйте столбцы с помощью unnamed