Pandas - добавить в CSV, несоответствующее количество столбцов - PullRequest
0 голосов
/ 06 мая 2020

Итак, я очищаю те же веб-страницы с помощью BS4, поскольку данные хранятся в таблицах, это довольно простой процесс. Определите таблицу и прочтите ее, используя: df1 = pd.read_html(str(table))

Проблема в том, что таблицы похожи, но не всегда одинаковы, то есть количество столбцов не всегда одинаковое. Например, в таблице на странице 1 есть следующие столбцы: Id, Name, DOB, College, Years_experience, Nationality, тогда как в той же таблице на странице 2 есть те же столбцы, что и для колледжа. Итак:

Id, Name, DOB, College, Years_experience, Nationality

vs

Id, Name, DOB, Years_experience, Nationality

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

Так что-то вроде: проверьте имена столбцов, если не найдены, заполните нулевые значения для всех строк.

Есть ли какое-то простое решение для этого, или мне нужно создать dict и сделать все вручную ?

Кстати; если есть общее лучшее решение для этой проблемы, это не нужно делать с помощью Pandas, просто я привык к этому, так как это очень легко читать HTML таблица

Я делаю что-то вроде :

Я делаю что-то вроде:

for urlx in urls:


url = str(urlx)
res = requests.get(url,headers=headers)
soup = BeautifulSoup(res.content,'lxml')



table = soup.find('table', id='abc')

df1 = pd.read_html(str(table))


df1[0]['URL'] = urlx


df1[0].to_csv('_out.csv', encoding='utf=8',float_format="%.3f", index=False, header=None , mode='a')

Спасибо

редактировать: добавлено больше информации

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Вы можете сделать это:

df = pd.DataFrame()
for urlx in urls:
    res = requests.get(url,headers=headers)
    soup = BeautifulSoup(res.content,'lxml')
    table = soup.find('table', id='abc')

    df1 = pd.read_html(str(table))[0]
    df1['URL'] = urlx

    df = df.append(df1, sort=False).reset_index(drop=True)

df.to_csv('file.csv', index=False)

Или, возможно, пропустить весь beautifulsoup и go прямо с pandas:

df = pd.DataFrame()
for urlx in urls:
    df1 = pd.read_html(urlx, attrs={'id':'abc'})[0]
    dfs['URL'] = urlx
    df = df.append(df1, sort=False).reset_index(drop=True)

df.to_csv('file.csv', index=False)

Вот ваш код:

import pandas as pd
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0)'}

#years_url = ['https://widgets.sports-reference.com/wg.fcgi?css=1&site=bbr&url=%2Fplayers%2Fi%2Fiversal01.html&div=div_playoffs_per_game']
years_url = ['https://www.basketball-reference.com/players/o/odomla01.html','https://www.basketball-reference.com/players/r/russebi01.html']

df = pd.DataFrame() #< Initialize empty dataframe before loop
for year_url in years_url:
    res = requests.get(year_url,headers=headers)
    soup = BeautifulSoup(res.content,'html.parser')
    table = soup.find('table', id='per_game')

    df1 = pd.read_html(str(table))[0]
    df1['player'] = year_url  #<---- HERE WAS YOUR ERROR
    df1['Name'] = soup.find('h1',{'itemprop':'name'}).text #<-- I added this

    df = df.append(df1, sort=False).reset_index(drop=True)

df.to_csv('123.csv', index=False) #<--- Took this out of the for loop

ИЛИ

import pandas as pd

#years_url = ['https://widgets.sports-reference.com/wg.fcgi?css=1&site=bbr&url=%2Fplayers%2Fi%2Fiversal01.html&div=div_playoffs_per_game']
years_url = ['https://www.basketball-reference.com/players/o/odomla01.html','https://www.basketball-reference.com/players/r/russebi01.html']

df = pd.DataFrame() #< Took this out of the for loop
for year_url in years_url:
    df1 = pd.read_html(year_url, attrs={'id':'per_game'})[0]
    df1['player'] = year_url
    df = df.append(df1, sort=False).reset_index(drop=True)

df.to_csv('123.csv', index=False) 
0 голосов
/ 06 мая 2020

это то, что вы ищете? :

import pandas as pd 
df1=pd.DataFrame(
    {
        'id':[1,3,4],
        'name':[1,5,7],
        'dob':[100,105,110]
                 })

df2=pd.DataFrame(
    {
        'id':[6,4,4],
        'name':[1,4,4],
        'dob':[10,10,12],
        'nationality':['usa','ger','swe'],
        'years':[11,22,33] })

print(df1)
   dob  id  name
0  100   1     1
1  105   3     5
2  110   4     7

print(df2)
   dob  id  name nationality  years
0   10   6     1         usa     11
1   10   4     4         ger     22
2   12   4     4         swe     33

df_list=[df1,df2]
df=pd.concat(df_list,sort=False)

print(df)

   dob  id  name nationality  years
0  100   1     1         NaN    NaN
1  105   3     5         NaN    NaN
2  110   4     7         NaN    NaN
0   10   6     1         usa   11.0
1   10   4     4         ger   22.0
2   12   4     4         swe   33.0
...