合并2个字典并将其存储在pandas数据框中,其中一个字典具有可变长度的列表元素

时间:2019-11-20 15:00:38

标签: python pandas dictionary beautifulsoup

我正在使用Beautiful Soup遍历一些HTML div:

for div in soup.findAll('a', {'class': 'result'}):
            adLink = div.a.get('href') 
            adInfo= {
                              u'adLink':adLink,
                              u'adThumbImg':...some code...,
                              u'adCounty':...some code...

                             }
            adFullInfo = getFullAdInfo(adLink)
            adInfo.update(adFullInfo) 

ads_CarsURL = pd.DataFrame(data=adInfo) #Create pandas DF

getFullAdInfo是函数

def getFullAdInfo  {
...some code...
}  

它返回的字典看起来像这样:

{'adID': '2027007',
 'adTitle': 'Ford 750 Special',
 'adDatePublished': '20.11.2009',
 'adTimePublished': '14:23',
 'adViewed': '102',
 'carPriceEUR': '600',
 'carManufacturer': 'Ford'}

因此,在每次迭代中,我都从adInfo字典和adFullInfo函数获取值,该函数返回另一个dict并将它们合并,这样我就可以得到单个字典记录。 想法最终是创建熊猫数据框。

我得到的错误是:

ValueError: arrays must all be same length

我不知道为什么,所以当我最初为每个字典键定义所有变量,并为它们分配空字符串时,像adID=""一样,以防丢失。

2 个答案:

答案 0 :(得分:3)

获得完整的广告后,将其转换为1行数据框,然后将其附加到最终数据框。这样可以解决长度不匹配的问题,也可以解决广告中没有其他可用数据的问题。您必须弄清楚逻辑,因为您没有提供要测试的那部分代码。下面是我意思的简短示例:

import pandas as pd

data1 = {'adID': '2027007',
 'adTitle': 'Ford 750 Special',
 'adDatePublished': '20.11.2009',
 'adTimePublished': '14:23',
 'adViewed': '102',
 'carPriceEUR': '600',
 'carManufacturer': 'Ford'}

data2 = {'adID': '20555',
 'adTitle': 'Honda',
 'adTimePublished': '11:23',
 'adViewed': '2',
 'carManufacturer': 'Honda'}

# Initialize empty dataframe
final_df = pd.DataFrame()

# Iterate through your dictionaries, convert to 1 row dataframe and append it to your final dataframe
for data in [data1, data2]:
    temp_df = pd.DataFrame(data, index=[0])

    final_df = final_df.append(temp_df, sort=True).reset_index(drop=True)

具体随您提供的信息,它类似于:

ads_CarsURL = pd.DataFrame()    
for div in soup.findAll('a', {'class': 'result'}):
            adLink = div.a.get('href') 
            adInfo= {
                              u'adLink':adLink,
                              u'adThumbImg':...some code...,
                              u'adCounty':...some code...

                             }
            adFullInfo = getFullAdInfo(adLink)
            adInfo.update(adFullInfo) 

            temp_df = pd.DataFrame(adInfo, index=[0])

            ads_CarsURL = final_df.append(temp_df, sort=True).reset_index(drop=True)

输出:

print (final_df.to_string())
  adDatePublished     adID adTimePublished           adTitle adViewed carManufacturer carPriceEUR
0      20.11.2009  2027007           14:23  Ford 750 Special      102            Ford         600
1             NaN    20555           11:23             Honda        2           Honda         NaN

答案 1 :(得分:0)

尝试了各种选择,这是产生最佳结果的原因:

我已将adFull = {**adBasicInfo,**adOtherInfo}的字典正确合并,并在每次迭代中将它们附加到adFullList列表中。

之后,我可以从adFullList列表中成功创建熊猫数据框。

其他解决方案无效,因为第二个字典具有某些值的元素列表类型。他们看起来像这样:

adFullDF.iloc[2]['carSafety']

给出:

['Self-tightening belts', 'Rear seat belts', 'Active head restraints']

在这种情况下,词典列表可以解决熊猫提出的形状问题,如果其中一个词典的某些条目具有可变长度的列表项,则当您尝试将词典保存在熊猫数据框中时,

为了更好的理解,某些词典的名称进行了更改:

adBasicInfo = {} # 1.st dictionary
adOtherInfo = {} # 2.nd dictionary
adFullInfo = {}  # Merged dictionary
adFullList = []  # List for appending merged dictionaries

# In each iteration merge dicts and append them in the list
 for div in soup.findAll('a', {'class': 'result'}):
           ..some code...
            adBasicInfo = {
                              u'adLink':adLink,
                              u'adThumbImg':...some code...,
                              u'adCounty':...some code...

                             }
        adOtherInfo = getFullAdInfo(adLink)      # Get complex dict      
        adFull = {**adBasicInfo,**adOtherInfo} # Merge dicts
        adFullList.append(adFull)              # Append dicts to list

# Save final version of list as pandas dataframe
adFullDF = pd.DataFrame(data=adFullList) # Save final list to dataframe