Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多栏标准_Python_Pandas - Fatal编程技术网

Python 多栏标准

Python 多栏标准,python,pandas,Python,Pandas,我试图根据多列上的某些条件替换Pandas数据框中的值。对于单列标准,这可以通过字典非常优雅地完成,例如: 输入df: 结果df2: 我试图将其扩展到多列上的条件,例如col1==1,col2==10->replace。对于单个标准,可以这样做: df3=df.copy() df3.loc[((df['col1']==1)&(df['col2']==10)), 'col1'] = 'c' 这将导致df3: 我在现实生活中遇到的问题有大量的条件,这将涉及大量的df3.loc[criter

我试图根据多列上的某些条件替换Pandas数据框中的值。对于单列标准,这可以通过字典非常优雅地完成,例如:

输入df:

结果df2:

我试图将其扩展到多列上的条件,例如col1==1,col2==10->replace。对于单个标准,可以这样做:

df3=df.copy()
df3.loc[((df['col1']==1)&(df['col2']==10)), 'col1'] = 'c'
这将导致df3:

我在现实生活中遇到的问题有大量的条件,这将涉及大量的df3.loc[criteria1&criteria2,column]=值调用,这远不如使用字典作为查找表进行替换。是否可以将优雅的解决方案df2=df.replace{col1:rdict}扩展到一个设置,其中一列中的值由基于多列的条件替换

这是我试图实现的一个例子,尽管在我的现实生活中,标准的数量要大得多:

输入df:

结果df3:


此方法可能比pandas功能更有效,因为它依赖于numpy数组和字典映射

import pandas as pd

df = pd.DataFrame({'col1': {0:1, 1:1, 2:2, 3:2}, 'col2': {0:10, 1:20, 2:10, 3:20}})

rdict = {(1, 10): 'a', (1, 20): 'b', (2, 10): 'c', (2, 20): 'd'}

df['col1'] = list(map(rdict.get, [(x[0], x[1]) for x in df1[['c1', 'c2']].values]))

此方法可能比pandas功能更有效,因为它依赖于numpy数组和字典映射

import pandas as pd

df = pd.DataFrame({'col1': {0:1, 1:1, 2:2, 3:2}, 'col2': {0:10, 1:20, 2:10, 3:20}})

rdict = {(1, 10): 'a', (1, 20): 'b', (2, 10): 'c', (2, 20): 'd'}

df['col1'] = list(map(rdict.get, [(x[0], x[1]) for x in df1[['c1', 'c2']].values]))
演示:

资料来源:

In [120]: df
Out[120]:
   col1  col2
0     1    10
1     1    10
2     1    20
3     1    20
4     2    10
5     2    20
6     3    30
条件和替换DF:

In [121]: cond
Out[121]:
   col1  col2 repl
1     1    20    b
2     2    10    c
0     1    10    a
3     2    20    d
解决方案:

In [121]: res = df.merge(cond, how='left')
收益率:

In [122]: res
Out[122]:
   col1  col2 repl
0     1    10    a
1     1    10    a
2     1    20    b
3     1    20    b
4     2    10    c
5     2    20    d
6     3    30  NaN   # <-- NOTE


In [123]: res['col1'] = res.pop('repl').fillna(res['col1'])

In [124]: res
Out[124]:
  col1  col2
0    a    10
1    a    10
2    b    20
3    b    20
4    c    10
5    d    20
6    3    30
演示:

资料来源:

In [120]: df
Out[120]:
   col1  col2
0     1    10
1     1    10
2     1    20
3     1    20
4     2    10
5     2    20
6     3    30
条件和替换DF:

In [121]: cond
Out[121]:
   col1  col2 repl
1     1    20    b
2     2    10    c
0     1    10    a
3     2    20    d
解决方案:

In [121]: res = df.merge(cond, how='left')
收益率:

In [122]: res
Out[122]:
   col1  col2 repl
0     1    10    a
1     1    10    a
2     1    20    b
3     1    20    b
4     2    10    c
5     2    20    d
6     3    30  NaN   # <-- NOTE


In [123]: res['col1'] = res.pop('repl').fillna(res['col1'])

In [124]: res
Out[124]:
  col1  col2
0    a    10
1    a    10
2    b    20
3    b    20
4    c    10
5    d    20
6    3    30
我们可以使用合并

假设您的df看起来像

df = pd.DataFrame({'col1': {0:1, 1:1, 2:2, 3:2, 4:2, 5:1}, 'col2': {0:10, 1:20, 2:10, 3:20, 4: 20, 5:10}})

    col1 col2
0   1    10
1   1    20
2   2    10
3   2    20
4   2    20
5   1    10
您的条件替换可以表示为另一个数据帧:

df_replace

  col1  col2    val
0   1   10      a
1   1   20      b
2   2   10      c
3   2   20      d

(As OP (Bart) pointed out, you can save this in a csv file.)
然后你可以用

df = df.merge(df_replace, on=["col1", "col2"], how="left")

    col1    col2    val
0   1       10      a
1   1       20      b
2   2       10      c
3   2       20      d
4   2       20      d
5   1       10      a
那你只需要放下可乐

正如MaxU所指出的,可能存在无法替换的行,从而导致NaN。我们可以用一条像这样的线

df["val"] = df["val"].combine_first(df["col1"])
如果合并后的结果值为NaN,则填写col1中的值。

我们可以使用merge

假设您的df看起来像

df = pd.DataFrame({'col1': {0:1, 1:1, 2:2, 3:2, 4:2, 5:1}, 'col2': {0:10, 1:20, 2:10, 3:20, 4: 20, 5:10}})

    col1 col2
0   1    10
1   1    20
2   2    10
3   2    20
4   2    20
5   1    10
您的条件替换可以表示为另一个数据帧:

df_replace

  col1  col2    val
0   1   10      a
1   1   20      b
2   2   10      c
3   2   20      d

(As OP (Bart) pointed out, you can save this in a csv file.)
然后你可以用

df = df.merge(df_replace, on=["col1", "col2"], how="left")

    col1    col2    val
0   1       10      a
1   1       20      b
2   2       10      c
3   2       20      d
4   2       20      d
5   1       10      a
那你只需要放下可乐

正如MaxU所指出的,可能存在无法替换的行,从而导致NaN。我们可以用一条像这样的线

df["val"] = df["val"].combine_first(df["col1"])

如果合并后的结果值为NaN,则填写col1中的值。

能否添加一个可复制的输入数据集和所需的数据集?能否给出一个更接近实际问题的示例数据集?我将更新该问题,以包括一个更现实的问题。能否添加一个可复制的输入数据集和所需的数据集数据集?您能给出一个更接近您的实际问题的示例数据集吗?我将更新该问题以包含一个更现实的问题。这不会产生与df3.loc[df['col1']==1&df['col2']==10,'col1']='c'相同的结果,它只会基于多个标准替换单个列中的值columns@Bart,这个解决方案怎么样?太好了,我喜欢它,因为它使用了与字典相同的方法进行替换,就像用于单列条件的df.replace{col1:rdict}方法一样。我必须看看性能上的差异是否与我的情况有关,如果是的话,这可能是我的首选解决方案。我编写了一个快速基准测试,这实际上似乎是较慢的系数~3.5,请参阅底部的基准测试结果。@Bart,感谢您为基准测试付出的努力。我稍微改变了我的逻辑,使用了一个小的加速。使用df merge方法失败的地方是convert_df的创建。包括convert_df和convert_dict的设置成本,我看到n_行=10000,cats=5的时间非常接近。如果您尝试n_rows=10000,cats=50,我发现convert_df的设置成本比convert_dict低约1.5s~600倍。因此您选择df.merge是正确的,但前提是映射是静态/构建一次/不从csv重复读取。这不会产生与df3.loc[df['col1']==1&df['col2']==10,'col1']='c'相同的结果,它只替换基于一个准则的单个列中的值columns@Bart,那么这个解决方案呢?太好了,我喜欢它,因为它使用了与字典相同的方法进行替换,比如用于单列条件的df.replace{col1:rdict}方法。我必须看看性能上的差异是否与我的情况有关,如果是的话,这可能是我的首选解决方案。我编写了一个快速基准测试,这实际上似乎是较慢的系数~3.5,请参阅底部的基准测试结果。@Bart,感谢您为基准测试付出的努力。我稍微改变了我的逻辑,使用了一个小的加速。使用df merge方法失败的地方是convert_df的创建。包括convert_df和convert_dict的设置成本,我看到n_行=10000,cats=5的时间非常接近。如果尝试n_rows=10000,cats=50,我发现convert_df的设置成本比convert_dict低约1.5s~600倍。因此,使用df.merge是正确的,但前提是映射是静态/构建一次/不重复r

ead来自csv。如前所述,我的实际问题有很多不同的条件,如cond=col1==1和col2==10,不幸的是,我不知道这是如何解决我的问题的。@巴特,好的,你有多个条件,但你有一个或多个替换dict吗?我不确定我是否理解,但你有一个或多个替换dict;我有多个条件,它们都映射到不同的替换值。有趣的解决方案是,如果我将cond建立在定义条件和替换的输入CSV文件上,这可能会很好地工作。我会试一试,除非有人给出一个更优雅的解决方案,否则我会接受这个答案。如前所述,我的现实生活问题有很多不同的条件,比如cond=col1==1和col2==10,不幸的是,我不知道这是如何解决我的问题的。@Bart,好的,你有多个条件,但你有一个或多个替换dict吗?我不知道我是否理解,但你有一个或多个替换dict;我有多个条件,它们都映射到不同的替换值。有趣的解决方案是,如果我将cond建立在定义条件和替换的输入CSV文件上,这可能会很好地工作。我会尝试一下,除非有人发布一个更优雅的解决方案,否则我会接受这个答案。太好了,这会管用的。例如,我可以从定义了条件/替换的CSV文件中创建df_替换,以保持代码干净。@Bart将其保存在另一个CSV文件中是个好主意!让我补充一下。你仍然需要处理那些不会被替换的行…@MaxU这是一个左合并,所以应该可以。df上不匹配的值将被保留。@MaxU,这就是你删除答案的原因吗?这似乎也是一个完美的解决方案。在我的例子中,col1和col2的所有组合都保证是著名的临终遗言。。映射到一个新的值。太好了,这将起作用。例如,我可以从定义了条件/替换的CSV文件中创建df_替换,以保持代码干净。@Bart将其保存在另一个CSV文件中是个好主意!让我补充一下。你仍然需要处理那些不会被替换的行…@MaxU这是一个左合并,所以应该可以。df上不匹配的值将被保留。@MaxU,这就是你删除答案的原因吗?这似乎也是一个完美的解决方案。在我的例子中,col1和col2的所有组合都保证是著名的临终遗言。。映射到新值。