【问题标题】:got incorrect mapping from dictionary to array in pandas?在熊猫中从字典到数组的映射不正确?
【发布时间】:2019-04-28 15:11:43
【问题描述】:

我打算合并两个数据框,芝加哥犯罪数据和 Redfin 房地产数据,但 Redfin 数据是按芝加哥社区收集的,而犯罪数据是按社区区域收集的。为此,我在芝加哥找到了neighborhood map,我有点想出如何将社区分配给社区。两个数据帧的结构有点不同,所以我做了一些步骤操作。以下是有关我尝试的详细信息:

示例数据 sn-p

这是我可以查看example data snippet 的公共要点。

这是我从网上收集的neighborhood mapping

我的解决方案

这是我的第一个映射解决方案:

code_pairs_neighborhoods = [[p[0], p[1]] for p in [pair.strip().split('\t') for pair in neighborhood_Map.strip().split('\n')]]
neighborhood_name_dic = {k[0]:k[1] for k in code_pairs_neighborhoods} #neighborhood -> community area

chicago_crime['neighborhood'] = chicago_crime['community_name'].map(neighborhood_name_dic)
Redfin['neighborhood'] = Redfin['Region'].map(neighborhood_name_dic)

final_df= pd.merge(chicago_crime, chicago_crime, on='neighborhood')

但是这个解决方案没有找到正确的映射,neighborhood 变成了 NAN,这是错误的。

第二次映射尝试

在不使用邻域映射的情况下,我直观地提出了这个映射解决方案:

chicago_crime['community_name']=[[y.split() for y in x] for x in chicago_crime['community_name']]
Redfin['Region']= [[j.split() for j in i] for i in Redfin['Region']]

idx, datavalue = [], []
for i,dv in enumerate(chicago_crime['community_name']):
    for d in dv:
        if d in Redfin['Region'][i]:   
            if i not in idx:
                idx.append(i)
                datavalue.append(d)

chicago_crime['merge_ref'] = datavalue
Redfin['merge_ref'] = datavalue

final_df= pd.merge(chicago_crime[['community_area','community_name','merge_ref']], Redfin, on='merge_ref')

但是这个解决方案给了我错误:ValueError: Length of values does not match length of index, AttributeError: 'list' object has no attribute 'split'

我怎样才能做到这一点?基于neighborhood mapping,如何获得 Redfin 数据和芝加哥犯罪数据的正确映射?有什么想法可以使此映射正确并获得正确的合并数据框吗?任何想法?提前致谢。

更新

我将包括数据集在内的所有解决方案都放在了这个 github 存储库 all solution and data on github

【问题讨论】:

  • 我们需要更多信息来帮助您,例如neighborhood_Map 是什么,您如何读取您发布的数据(例如,chicago_crime 是否来自 read_csv?),您想通过所有这些 split() 实现什么目标?也许您可以给我们 2-3 行输入和您想要的输出?
  • 您不能将您的主要代码包含在您链接到的 Github 中(或者这不是您的 github 存储库吗?)?另外,我认为编辑您的问题,使其包括您如何创建Redfinchicago_crimeneighborhood_Map 等,将非常有帮助
  • 您是否查看了我链接到的文章(在我的答案的最底部)并决定了您需要哪种类型的加入?您应该能够“玩转”不同的合并,看看什么最适合您!
  • 你仍然可以使用我之前发布的pd.merge(…),只要确保你在Update2 之前 合并。下面的代码框只是为了证明您将在内部联接中更新 46 个条目。

标签: python pandas


【解决方案1】:

好的,这就是我找到的:

  • neighborhood_Map 的第一行中有一个您可能想要删除的 unicode 字符:Cabrini\xe2\x80\x93Green'-> Cabrini Green
  • 切换neighborhood_name_dic 中的键和值,因为您想将现有的“罗杰斯公园”映射到附近的“东罗杰斯公园”,如下所示:

    neighborhood_name_dic = {k[1]:k[0] for k in code_pairs_neighborhoods}

我们仍然无法从您的代码中了解您在 Redfin data 中的阅读情况,但我认为您必须先删除 Region 列中的 Chicago, IL - 部分,然后才能合并?


更新:所以我想我设法理解了你的代码(再次,请在发布之前尝试清理一下这些东西),我认为@987654330 @ 等于 house_df 那里。因此,而不是说:

house_df=house_df.set_index('Region',drop=False)

我建议创建一个社区专栏:

house_df['neighborhood'] = house_df['Region'].map(lambda x: x.lstrip('Chicago, IL - '))

然后你可以合并:

crime_finalDF = pd.merge(chicago_crime, house_df, left_on='neighborhood', right_on='neighborhood')

要测试它,请尝试:

mask=(crime_finalDF['neighborhood']==u'Sheridan Park')
print(crime_finalDF[['robbery','neighborhood', u'2018-06-01 00:00:00']][mask])

产生:

   robbery   neighborhood  2018-06-01 00:00:00
0    140.0  Sheridan Park                239.0
1    122.0  Sheridan Park                239.0
2    102.0  Sheridan Park                239.0
3    113.0  Sheridan Park                239.0
4    139.0  Sheridan Park                239.0

所以两个数据集的成功连接(我认为)。

更新 2,关于 merge() 的成功。

这就是我读入并清理您的xlsx 文件的方式:

house_df = pd.read_excel("./real_eastate_data_main.xlsx",)
house_df.replace({'-': None})
house_df.columns=house_df.columns.astype(str)

house_df = house_df[house_df['Region'] != 'Chicago, IL']
house_df = house_df[house_df['Region'] != 'Chicago, IL metro area']

house_df['neighborhood'] = house_df['Region'].str.split(' - ')## note the surrounding spaces
house_df['neighborhood'] = house_df['neighborhood'].map(lambda x: list(x)[-1])

chicago_crime['neighborhood'] = chicago_crime['community_name'].map(neighborhood_name_dic)

## Lakeview and Humboldt park not defined in neighborhood_name_dic
# print( chicago_crime[['community_name','neighborhood']][pd.isnull(chicago_crime['neighborhood'])] )
chicago_crime = chicago_crime[~pd.isnull(chicago_crime['neighborhood'])] ## remove them

现在我们开始寻找两个 df 中的所有独特邻域

cc=sorted(chicago_crime['neighborhood'].unique())
ho=sorted(house_df['neighborhood'].unique())

print(30*u"-"+u" chicago_crime: "+30*u"-")
print(len(cc),cc)
print(30*u"-"+u" house_df: "+30*u"-")
print(len(ho),ho)
print(60*"-")
# print('\n'.join(cc))

set1 = set(cc)
set2 = set(ho)

missing = list(sorted(set1 - set2))
added = list(sorted(set2 - set1))

print('These {0} are missing in house_df: {1}'.format(len(missing),missing))
print(60*"-")

print('These {0} are only in house_df: {1}'.format(len(added),added))

这表明 29 在 house_df 中丢失(例如“East Pilsen”)而 132 只在 house_df 中找到(例如“Albany Park”),即我们可以“内连接”只有 46 个条目。

现在您必须决定如何继续,最好先read this 了解合并的工作方式(例如了解那里发布的维恩图),然后您可以自己改进代码因此! 或者: 以前手动清理数据,有时没有全自动的解决方案!

【讨论】:

    猜你喜欢
    • 2019-07-30
    • 2021-04-30
    • 2020-09-25
    • 2019-09-28
    • 2023-01-09
    • 2023-03-29
    • 1970-01-01
    • 2014-08-04
    相关资源
    最近更新 更多