在Python中查找CSV文件中的数据

kfgdxczn  于 2022-12-06  发布在  Python
关注(0)|答案(4)|浏览(259)

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

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
x8diyxa7

x8diyxa71#

下面是一种在Python中不使用
1.将两个CSV文件读入两个单独的词典列表,其中每个词典表示CSV文件中的一行。
1.遍历CSV1中的字典列表,对于每个字典,在CSV2中的字典列表中搜索匹配的Bin_Name。
1.如果找到匹配项,则使用CSV2中匹配字典中的Quantity值更新CSV1中字典中的Quantity值。
1.将CSV1中更新的词典列表写回新的CSV文件。
下面是上述步骤的一个示例实现:

# Import the csv module to read and write CSV files
import csv

# Open the two CSV files in read mode
with open("CSV1.csv", "r") as csv1_file, open("CSV2.csv", "r") as csv2_file:
    # Use the csv reader to read the CSV files into lists of dictionaries
    csv1_reader = csv.DictReader(csv1_file)
    csv1_data = list(csv1_reader)

    csv2_reader = csv.DictReader(csv2_file)
    csv2_data = list(csv2_reader)

    # Iterate over the list of dictionaries from CSV1
    for row in csv1_data:
        # Search for a matching Bin_Name in the list of dictionaries from CSV2
        match = next((r for r in csv2_data if r["Bin_Name"] == row["Bin_Name"]), None)

        # If a match is found, update the Quantity value in the dictionary from CSV1
        # with the Quantity value from the matching dictionary in CSV2
        if match:
            row["Quantity"] = match["Quantity"]

    # Open a new CSV file in write mode
    with open("updated_csv1.csv", "w") as updated_csv1_file:
        # Use the csv writer to write the updated list of dictionaries to the new CSV file
        csv1_writer = csv.DictWriter(updated_csv1_file, fieldnames=csv1_reader.fieldnames)
        csv1_writer.writeheader()
        csv1_writer.writerows(csv1_data)
kqhtkvqz

kqhtkvqz2#

在这种情况下,我会简单地使用panda * 内置 * 函数,不需要循环。
因此,假设没有重复的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
66bbxpm5

66bbxpm53#

我不确定我是否完全理解了你的问题,但请让我知道这是否回答了你的挑战。
在Python中执行Excel类型操作的通常方式是使用框架Pandas。使用这个框架,你可以用Python代码读取、操作和保存CSV文件(以及许多其他格式)。

设置示例

编辑:确保您已经安装了panda,例如在您的终端中输入以下内容: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

我对你的问题的理解是,你想指定哪些bin应该从你的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库中提供的更高效的内置方法相比,遍历行是一种非常慢的方法
1.这种方法在两个CSV文件中有重复的bin时很容易受到攻击
1.这种方法在bin仅存在于其中一个CSV文件中的情况下容易受到攻击
1.由于我们一次只更新一个单元格,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的等效操作)

o0lyfsai

o0lyfsai4#

嗨,你可以简单地先迭代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)

相关问题