【问题标题】:Searching a Python Dictionary with multiple values搜索具有多个值的 Python 字典
【发布时间】:2018-07-05 23:05:57
【问题描述】:

我在以下 CSV 文件中有数据,可在此处找到:

http://s000.tinyupload.com/index.php?file_id=87473936848618674050

CSV 的屏幕截图:

我编写了以下代码,将 CSV 文件作为 Pandas 数据框导入 Python,然后创建字典 dict。字典必须有名称和区域作为键,Windows 和 Linux 价格作为字典值。

#Import libraries and CSV file into dataframe, renaming columns, printing head

import pandas as pd

df = pd.read_csv('file.csv')

col_names = ['Name','Region','API', 'Memory','vCPU', 'Storage', 'Linux', 'Windows' ]

df.columns = col_names

#Creating Dict
dict = {}

for i in df.index:

    key = (df.at[i, 'Name'] , df.at[i, 'Region'])
    value = (df.at[i, 'vCPU'], df.at[i, 'Memory'], df.at[i, 'Storage'], df.at[i, 'Windows'] , df.at[i, 'Linux'])

    dictionary = {key:value}
    dict.update(dictionary)

我现在想编写一个函数来搜索字典。

例如,用户将为 vCPU 输入“32”,该函数将为具有 32 个 vCPU 的任何处理器返回区域、名称以及 Linux 和 Windows 价格。

稍后,我想实现这个针对 vCPU、Memory 和 Storage 的搜索功能。 (完整的 CSV 有 1700 行)。非常感谢有人帮助我。

【问题讨论】:

    标签: python pandas dictionary dataframe search


    【解决方案1】:

    为什么不只搜索数据框?您的查询代码可以概括以下内容。

    for index, row in df.loc[df['vCPU'] == '32 vCPUs'].iterrows():
        print (row['Region'] + ', ' + row['Name'] + ', Linux price: '+ row['Linux'] + ', Windows price: '+ row['Windows'])
    

    输出:

    US West - NorCal, Cluster Compute Eight Extra Large, Linux price: unavailable, Windows price: unavailable
    US East - Ohio, I2 Eight Extra Large, Linux price: $6.820000 hourly, Windows price: $7.782000 hourly
    APAC - Singapore, I3 High I/O Eight Extra Large, Linux price: $2.992000 hourly, Windows price: $4.464000 hourly
    

    这里有更多代码可以回答您的后续 cmets。上面,我展示了如何在数据框中查找数据。这里有更多代码,我希望能够充分展示如何去除“GiB”之类的标签、转换为值、迭代匹配值等。您有几个用例,所以我希望这段代码为您提供构建的基础上。要获得最接近的匹配,请参阅this question 的答案。

    # strip out the "GiB" and convert to float values
    df['Memory'] = df['Memory'].str.split(' ').str[0].astype(float)
    
    # use whatever code you need to get input from user
    cpu_request = '2 vCPUs'
    mem_request = 3
    
    matches = df.loc[(df['vCPU'] == cpu_request)]
    if matches.empty == 'True':
        print ('No matches.')
    else:
        for index, row in matches.loc[(matches['Memory'] >= mem_request)].iterrows():
            print(row['Name'] + ':')
            # you could add another loop here if your data can have multiple entries per name.
            print ('\t' + row['Region'] + ', ' + str(row['Memory']) + ' GiB, Linux price: '+ row['Linux'] + ', Windows price: '+ row['Windows'])
    

    【讨论】:

    • 这也有效。我将如何更改此代码以接受多个变量的用户输入?例如,如果我想输入 vCPU 和内存,并输出它们。或者,如果 vCPU 匹配但内存不匹配,我将如何输出具有 vCPU 匹配但具有下一个最高内存级别的处理器?
    • 另外,我喜欢你的格式。但是,它列出了每个结果,而与区域无关。我希望结果只显示一次名称,然后是该产品在每个地区的价格。假设每个处理器“名称”在 15 个地区具有相同的属性,但每个地区的价格不同
    【解决方案2】:

    如果您有多个键值,您将覆盖所有数据。

    In [4]: d = {}
    
    In [5]: d.update({1:1})
    
    In [6]: d.update({1:2})
    
    In [7]: d
    Out[7]: {1: 2}
    

    您必须创建一个dict,并带有一个到值列表的键映射

    for i in df.index:
        key = (df.at[i, 'Name'] , df.at[i, 'Region'])
        value = (df.at[i, 'vCPU'], df.at[i, 'Memory'], df.at[i, 'Storage'], df.at[i, 'Windows'] , df.at[i, 'Linux'])
    
        if key in dict:
            dict[key].append(value)
        else:
            dict[key] = [value]
    

    但所有这些都是多余的。您应该使用DataFrame

    【讨论】:

    • 在这种情况下我是否将 d 设置为等于某个值?我只调用 d,它并没有使用您的代码提取所有键和值,只是其中的一些
    • 有什么方法可以在这段代码中获取逻辑吗?例如,如果 CPU 不匹配,我如何让它返回下一个最高的 CPU(以内核为单位)?
    猜你喜欢
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    相关资源
    最近更新 更多