使用列(系列)作为键访问字典中的值,并将这些值与另一列进行比较

2024-09-29 23:19:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含两列的数据框架,还有一个单独的字典来帮助验证列中的值。列A是一系列键,列B应该具有与键关联的正确值。列C是我希望获得的输出列,在检查列a(dict中的键)是否能够获得列B中相应行中的匹配值后,使用一个布尔值

字典是这样的:

countries_dict = {"ANZ": "apj_anz", "AU":"apj_aus", "NZ":"apj_nzl"}

显示列A、B和所需输出列C的图像:

image

我尝试了下面的代码,使用一个helper列来比较使用Col a和Col B找到的值,并将结果bool放在Col C中

countries_dict = {"ANZ": "apj_anz", "AU":"apj_aus", "NZ":"apj_nzl"}

df["helper"] = df["A"].map(countries_dict)
df["C"] = df["helper"] == df["B"]

然而,这给了我以下的错误

numpy.core._exceptions.MemoryError: Unable to allocate 37.8 GiB for an array with shape (71187, 71187) and data type object

这可能是因为我的数据集中有超过70k行,不知道是否有更节省内存的方法来实现这个结果

任何关于如何解决此问题的建议都将不胜感激


我自己解决了这个问题:

在程序的前面,我使用regex从另一列(Col E)中提取字符串,并将其与另一列(Col D)的值进行比较,以在Col F处设置布尔值

df['F'] = (df["E"].str.lower()).str.extract(r'-20....(.*?)_') == df["D"]

当我将上述内容替换为以下内容时,脚本开始工作:

df['F'] = (df['E'].str.lower()).str.extract(r'-20....(.*?)_')
df['F'] = df['F'] == df['D']

我仍然不知道这到底是为什么发生的,但既然它起作用了,我想结束这个问题。谢谢所有回答的人!非常感谢🙏


Tags: 数据helperdf字典colcountriesdictau
2条回答

您可以尝试以下方法:

df['C'] = np.where(df.B.eq(df.A.map(countries_dict)), True, False)

输出:

    A   B       C
0   ANZ apj_anz True
1   ANZ apj_aus False
2   AU  apj_aus True
3   NZ  apj_nzl True
4   ANZ apj_anz True
5   ANZ apj_aus False
6   AU  apj_aus True
7   NZ  apj_nzl True
8   ANZ apj_anz True
9   ANZ apj_aus False

这将避免创建helper列,从而减少内存使用

您还可以尝试将列AB转换为分类列,以防这些列中的不同元素数量较少。这将进一步减少内存消耗并提高性能

示例:

为a列和B列创建了具有10个不同值的样本df

转换前:

Data columns (total 2 columns):
 #   Column  Non-Null Count    Dtype 
 -                    - 
 0   A       1000000 non-null  object
 1   B       1000000 non-null  object
dtypes: object(2)
memory usage: 22.9+ MB

%%timeit
df['C'] = np.where(df.B.eq(df.A.map(countries_dict)), True, False)

63.6 ms ± 499 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

将列转换为类别后:

Data columns (total 2 columns):
 #   Column  Non-Null Count    Dtype   
 -                    -   
 0   A       1000000 non-null  category
 1   B       1000000 non-null  category
dtypes: category(2)
memory usage: 9.5 MB

%%timeit
df['C'] = np.where(df.B.eq(df.A.map(countries_dict)), True, False)

3.07 ms ± 47.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

对于这里的小样本数据,您的代码似乎运行良好。问题可能是由于原始数据集太大,并且在定义新的帮助器列和其他中间结果的过程中内存不足

您可以尝试减少内存使用,而无需定义以下帮助器列:

您可以将列A映射为countries_dict,比较映射结果是否等于列B。该比较结果(布尔真/假)可以很容易地设置为新列C,如下所示:

df['C'] = df['A'].map(countries_dict) == df['B']

结果:

print(df)

     A        B      C
0  ANZ  apj_anz   True
1  ANZ  apj_aus  False
2   AU  apj_aus   True
3   NZ  apj_nzl   True
4  ANZ  apj_anz   True
5  ANZ  apj_aus  False
6   AU  apj_aus   True
7   NZ  apj_nzl   True
8  ANZ  apj_anz   True
9  ANZ  apj_aus  False

相关问题 更多 >

    热门问题