【问题标题】:How to do a Lookup of Data from a CSV file in Python?如何在 Python 中从 CSV 文件中查找数据?
【发布时间】:2022-12-28 16:42:17
【问题描述】:

我如何在 Python 中实现这一点。我知道 excel 中有一个 vlookup 函数,但如果 Python 中有方法,我更喜欢用 Python 来实现。基本上我的目标是从 CSV2 列数量中获取数据,并根据 Bin_Name 将数据写入 CSV1 列数量。脚本不应一次复制所有值,必须通过选择 Bin_Name 来复制。例如:今天,我想从 CSV2 的 Bin_Name ABCDE 获取数据到 CSV1,然后它将数据写入 CSV1 的列数量。如果这是可能的,我将非常感激并从中学到很多东西。非常感谢你提前。

CSV1                     CSV2

Bin_Name   Quantity      Bin_Name   Quantity
A                        A          43  
B                        B          32
C                        C          28
D                        D          33 
E                        E          37   
F                        F          38
G                        G          39
H                        H          41

【问题讨论】:

    标签: python csv lookup


    【解决方案1】:

    我会简单地使用熊猫内置在这种情况下起作用,不需要循环。

    因此,假设没有重复的 bin 名称,请尝试使用以下代码复制整列:

    df1= pd.read_csv("file1.csv")
    df2= pd.read_csv("file2.csv")
    
    df1["Quantity"]= df2["Quantity"].where(df1["Bin_Name"].eq(df2["Bin_Name"]))
    
    print(df1)
    
      Bin_Name  Quantity
    0        A        43
    1        B        32
    2        C        28
    3        D        33
    4        E        37
    5        F        38
    6        G        39
    7        H        41
    

    如果您只需要复制行的子集,请使用 boolean indexingpandas.DataFrame.loc

    ​
    vals= ["A", "B", "C", "D"]
    df1.loc[df1["Bin_Name"].isin(vals), "Quantity"] = df2.loc[df1["Bin_Name"].isin(vals), "Quantity"]
    print(df1)
    
      Bin_Name  Quantity
    0        A      43.0
    1        B      32.0
    2        C      28.0
    3        D      33.0
    4        E       NaN
    5        F       NaN
    6        G       NaN
    7        H       NaN
    

    【讨论】:

    • 感谢您的回复@abokey,我会试一试并让您知道。感谢你的帮助!
    • 我如何从整个代码开始,我觉得这些不完整?对不起,我只是个初学者呵呵呵呵,但非常感谢您的帮助。
    • 你好@abokey,先生,这里需要你的帮助:)谢谢
    • 要实现代码,您只需将"file1.csv""file2.csv" 替换为您的.csv 文件的实际路径/名称。
    • 感谢您的回复。我确实更改了文件的路径,但收到此错误消息:Traceback (most recent call last): Traceback (most recent call last): File "C:LookupQty.py", line 7, in <module> df1[" Quantity"]= df2["Quantity"].where(df1["Bin_Name"].eq(df2["Bin_Name"])) 文件“C:rame.py”,第 3805 行,在获取项目indexer = self.columns.get_loc(key) 文件“C:ase.py”,第 3805 行,在 get_loc raise KeyError(key) from err KeyError: 'Quantity'
    【解决方案2】:

    我不太确定我是否完全理解你的问题,但如果这能解决你的挑战,请告诉我。

    在 Python 中执行 Excel 类型操作的通常方法是使用框架Pandas。使用它,您可以使用 Python 代码读取、操作和保存您的 CSV 文件(以及许多其他格式)。

    设置示例

    编辑:确保你已经安装了熊猫,例如在您的终端中输入以下内容:pip install pandas

    由于我没有您的 CSV 文件,我将使用 Pandas 创建它们,而不是使用内置的 read_csv()-方法。

    import pandas as pd
    
    csv1 = pd.DataFrame.from_dict({
        "Bin_Name": ["A","B","C","D","E","F","G","H"],
        "Quantity": []
    }, orient="index").T
    
    csv2 = pd.DataFrame.from_dict({
        "Bin_Name": ["A","B","C","D","E","F","G","H"],
        "Quantity": [43, 32, 28, 33, 37, 38, 39, 41]
    }, orient="index").T
    

    我理解您的问题的方式是,您想指定应将哪些垃圾箱从您的csv1-文件复制到您的csv2-文件。在你的例子中,你提到了这样的事情:

    # Specify bins you want to copy
    bins_to_copy = ["A", "B", "C", "D", "E"]
    

    现在,有几种方法可以执行您提到的复制操作。有些比其他的好。既然你明确地说“脚本不应一次复制所有值”,我会按照你的指示给出一个建议,一个我认为是更好的方法。

    解决方案 1(不好 - 使用 for 循环)

    # Loop through each bin and copy cell value from csv2 to csv1
    for bin_to_copy in bins_to_copy:
        csv1.loc[csv1["Bin_Name"]==bin_to_copy, "Quantity"] = csv2.loc[csv2["Bin_Name"]==bin_to_copy, "Quantity"]
    
    # OUTPUT:
    > csv1
      Bin_Name Quantity
    0        A       43
    1        B       32
    2        C       28
    3        D       33
    4        E       37
    5        F     None
    6        G     None
    7        H     None
    

    这种方法正是我相信你所要求的。但是,它有几个弱点:

    1. 与使用 Pandas 库中提供的更高效的内置方法相比,循环遍历行是一种非常慢的方法
    2. 该方法容易受到在任一 CSV 文件中有重复 bin 的情况的影响
    3. 该方法容易受到 bin 仅存在于其中一个 CSV 文件中的情况的影响
    4. 因为我们一次更新一个单元格,Pandas 不明白列的数据类型已经改变,我们仍然为缺失值留下 None(以及一个“对象”类型的列)而不是NaN(这将指示数字(浮点)列数据类型)。

      如果我正确理解了您的问题,那么更好的方法如下

      解决方案 2(更好 - 使用合并)

      # Select the columns with bins from csv1
      csv1_bins = csv1["Bin_Name"]
      
      # Select only the rows with the desired bins from csv2
      csv2_desired_bins = csv2[csv2["Bin_Name"].isin(bins_to_copy)]
      
      # Merge the columns (just "Quantity" in this case) from csv2 to csv1 using "Bin_Name" as "merging-key"
      result = pd.merge(left=csv1_bins, right=csv2_desired_bins, on="Bin_Name", how="left")
      
      # OUTPUT
      > result
        Bin_Name Quantity
      0        A       43
      1        B       32
      2        C       28
      3        D       33
      4        E       37
      5        F      NaN
      6        G      NaN
      7        H      NaN
      

      merge()-方法更强大,可以解决我列出的解决方案 1 中的所有挑战。它也是 join()-方法的更通用版本,根据文档,它是“就像 Excel VLOOKUP 操作一样。”(这就是你提到的相当于你的 Excel)

    【讨论】:

    • 感谢@ViggoTW 的回复,我会试一试,然后告诉你。感谢你的帮助!
    • 我确定你的选择很棒,但我正在尝试重新创建它,但我不断收到此错误:Traceback(最近一次调用):文件“C:\LookupQty.py”,第 46 行,在 <module> import pandas作为 pd ModuleNotFoundError:没有名为“pandas”的模块
    • 此外,BIN_NAME 和 Quantity 上会有随机数据,因此它并不总是 ["A","B","C","D","E","F","G","H"] 和数字.如果我需要整个脚本,我深表歉意,因为我是这方面的初学者。非常感谢您的协助。
    • 我建议尝试用谷歌搜索您收到的错误消息,因为我看到您在其他回复中发布了几条微不足道的错误消息。我没有足够的堆栈信用来回复其他 cmet,但是“ModuleNotFoundError:没有名为‘pandas’的模块”错误意味着您还没有安装 pandas。您需要先在终端中运行“pip install pandas”。
    【解决方案3】:

    您好,您可以先简单地迭代 CSV2,然后在收集到想要的值后,您可以在 CSV1 中搜索它。我在下面写了一段代码,它可能会对你有所帮助,但可以有更有效的方法。

    def func(wanted_rows: list,csv2df: pd.DataFrame):
        # Iterate csv2df
        for index,row in csv2df.iterrows():
            # Check if index in the wanted list
            if index in wanted_rows:
                # Get index of CSV1 for same value
                csv1_index = CSV1[CSV1.Bin_Name == row['Bin_Name']].index[0]
                CSV1.at[csv1_index,'Quantity'] = row['Quantity']
        return df
    
    wanted_list = [1,2,3,4,5]
    func(wanted_list,CSV2df)
    

    【讨论】:

    • 感谢您对@VolkanM 的回复,我会试一试并让您知道。感谢你的帮助!
    • 抱歉,我是 Python 初学者,我认为您的分享也很完整? :) 我该如何更正这个先生? IndentationError:在第 2 行的函数定义之后需要一个缩进块
    • 这意味着您在 for 或 if 语句下添加了额外的选项卡。我已经编辑了我的第一条评论,也许它可以帮助您解决问题
    • 文件“C:LookupQty.py”,第 13 行 return df ^^^^^^^^^ SyntaxError: 'return' outside function Process finished with exit code 1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 2016-09-27
    相关资源
    最近更新 更多