合并两个字典并将它们存储在Pandas数据框中,其中一个字典具有可变长度列表元素。

3

我正在使用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函数中获取值,然后合并它们,以便我可以有单个字典记录。想法是最终创建pandas数据帧。
我得到的错误是:
ValueError: arrays must all be same length
我不知道为什么会这样,当我最初为每个字典键定义所有变量并将空字符串(如adID="")分配给它们以防它们丢失时。

你是如何将它们合并为一个数据框的?如果你只是将“temp dataframe”附加到最终的数据框中,那么你就不需要担心长度,它会自动填充为 null。 - chitown88
2个回答

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

数值错误:无法将形状为(4)的输入数组广播到形状为(1)的数组 - 这是针对temp_df = pd.DataFrame(adInfo,index = [0])的。 - Hrvoje
@Harvey 你还需要帮助吗? - αԋɱҽԃ αмєяιcαη
@Harvey,你使用的pandas版本是哪个? - chitown88

0

尝试了各种选项,这是给出最佳结果的方法:

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

之后,我可以成功地从adFullList列表创建pandas数据帧。

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

adFullDF.iloc[2]['carSafety']

这将会给出:

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

在编程中,如果您尝试将字典保存到 pandas 数据框中时,其中一个字典的某些项具有可变长度列表项,那么字典列表可以解决 pandas 将出现的形状问题。
为了更好地理解,一些字典的名称已更改。
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接