【问题标题】:Pandas dataframe loop all values for certain column熊猫数据框循环特定列的所有值
【发布时间】:2021-06-28 08:40:57
【问题描述】:

使用 pandas 数据框假设我有类似结构的数据框如下:

import pandas as pd
a_choise = ["True", "False", "False", "False", "True", "False", "False", "True", "True"]
b_choise = ["True", "True", "False", "False", "False", "False", "True", "True", "True"]
c_choise = ["False", "False", "True", "False", "True", "True", "False", "True", "False"]
a_n = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9"]
b_n = ["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9"]
c_n = ["c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9"]
df = pd.DataFrame(
    {"a": list(range(1, 10)), "b": list(range(11, 20)), "c": range(21, 30), 
     "a_Cho":a_choise, "b_Cho":b_choise, "c_Cho":c_choise,
     "a_n":a_n, "b_n":b_n, "c_n":c_n}
)
    a   b   c   a_Cho   b_Cho   c_Cho   a_n b_n c_n
0   1   11  21  True    True    False   a1  b1  c1
1   2   12  22  False   True    False   a2  b2  c2
2   3   13  23  False   False   True    a3  b3  c3
3   4   14  24  False   False   False   a4  b4  c4
4   5   15  25  True    False   True    a5  b5  c5
5   6   16  26  False   False   True    a6  b6  c6
6   7   17  27  False   True    False   a7  b7  c7
7   8   18  28  True    True    True    a8  b8  c8
8   9   19  29  True    True    False   a9  b9  c9

我想要一个满足以下条件的新 2 列(Choise、Value) 对于“a_Cho”、“b_Cho”和“c_Cho”中的所有值

  • 如果 "a_Cho" = true then choise = "a_n", value = a 对应 "a_Cho" 的值 elif "a_Cho" = false 然后移到下一个
  • 如果 "b_Cho" = true then choise = "b_n", value = b 对应 "b_Cho" 的值如果 "b_Cho" = false 然后移到下一个
  • 如果 "c_Cho" = true then choise = "c_n", value = c 对应 "c_Cho" 的值如果 "c_Cho" = false 然后移到下一个
  • 如果 "x_Cho" = false 那么 value 和 choise = "Invalide"

【问题讨论】:

  • df_val = [] df_name = [] cols = ["coln_present", "colm_present", ".... ] for x in df[cols]: if df1['coln_present'][df1 ['coln_present'] ==True]: df_val.append(df1.coln_val) df_name.append(df1.p1_coln_name) elif df1['colm_present'][df1['colm_present'] ==True]: df_val.append(df1 .colm_val) df_name.append(df1.p1_colm_name) else: df_val.append("Not_Valid") df_name.append("Not_Valid") ##
  • 我在帖子中添加了一个示例代码

标签: python pandas dataframe pandas-loc


【解决方案1】:

已编辑

感谢您更新您的问题。经过您的编辑,我相信.loc 会对您有用。 .loc 允许我们执行“逻辑索引”,根据列相等性抓取行。

例如,以下获取列a_Cho 等于"True" 的所有行,

>>> df.loc[df.a_Cho.eq('True'), ['a_n', 'a']]
    a   b   c   a_Cho   b_Cho   c_Cho   a_n b_n c_n
0   1   11  21  True    True    False   a1  b1  c1
4   5   15  25  True    False   True    a5  b5  c5
7   8   18  28  True    True    True    a8  b8  c8
8   9   19  29  True    True    False   a9  b9  c9

我们还可以使用.loc 选择列的子集。

>>> df.loc[df.a_Cho.eq("True"), ["a_n", "a"]].rename(columns={"a_n": "choise", "a": "value"})

我使用.rename() 重命名列。

使用上述方法,我们可以为您陈述的每个条件执行逻辑索引,然后将结果连接起来。

def new_col_names(x):
    return {x + "_n": "choise", x: "value"}

# logical criteria
only_a = df.a_Cho.eq("True")
only_b = df.a_Cho.eq("False") & df.b_Cho.eq("True")
only_c = df.a_Cho.eq("False") & df.b_Cho.eq("False") & df.c_Cho.eq("True")
invalid = df.a_Cho.eq("False") & df.b_Cho.eq("False") & df.c_Cho.eq("False")

df_a = df.loc[only_a, ["a_n", "a"]].rename(columns=new_col_names("a"))
df_b = df.loc[only_b, ["b_n", "b"]].rename(columns=new_col_names("b"))
df_c = df.loc[only_c, ["c_n", "c"]].rename(columns=new_col_names("c"))
df_inv = df.loc[invalid].assign(choise="invalide", value="invalide").copy()
df_inv = df_inv[["choise", "value"]]

df_new = pd.concat([df_a, df_b, df_c, df_inv])

最终的DataFrame 看起来像:

    choise    value
0   a1         1
4   a5         5
7   a8         8
8   a9         9
1   b2        12
6   b7        17
2   c3        23
5   c6        26
3   invalide  invalide

请注意,左侧的索引值显示了每个条目的原始行号。如果您不关心这些数字,可以将ignore_index=True 选项传递给.concat

这更接近你想要的吗?

原创

您好,欢迎来到 StackOverflow!我不确定我是否完全理解你的问题。例如,在您的示例代码中,您似乎没有在每次迭代中使用循环变量x。查看与您正在使用的具有相同结构的示例DataFrame 可能会有所帮助。

我的印象是您的问题可能类似于使用pd.meltthis question

您的DataFrame 的结构是否如下?

>>> import pandas as pd
>>> df = pd.DataFrame(
    {"A": list(range(1, 10)), "B": list(range(11, 20)), "C": range(21, 30)}
)
>>> df.head()

    A   B   C
0   1   11  21
1   2   12  22
2   3   13  23
3   4   14  24
4   5   15  25
5   6   16  26
6   7   17  27
7   8   18  28
8   9   19  29

如果是这样,您可以使用pd.melt 对其进行重组,使其具有两列,即“列名”列和“列值”列,正如您在问题中所描述的那样。

上面示例DataFrame 的命令和输出将是:

>>> pd.melt(df, value_vars=['A', 'B', 'C'])

  variable  value
0   A   1
1   A   2
2   A   3
3   A   4
4   A   5
5   A   6
6   A   7
7   A   8
8   A   9
9   B   11
10  B   12
11  B   13
12  B   14
13  B   15
14  B   16
15  B   17
16  B   18
17  B   19
18  C   21
19  C   22
20  C   23
21  C   24
22  C   25
23  C   26
24  C   27
25  C   28
26  C   29

这和你问的一样吗?如果没有,您能否提供一个您正在使用的DataFrame 的示例以及您希望最终结果看起来如何的示例?它可以是一个简化的或“模拟”的例子。

【讨论】:

  • 感谢 Alex Kluber 的回复,数据与上面的布尔列 A_bol、B_bol、C_bol 几乎相同,我需要一个列来检查 A_bol = true 然后返回 A 值,如果为 false 检查 B_bol等等
  • 我已经更新了我的答案@Abdelsabour。这能回答你的问题吗?
猜你喜欢
  • 2020-07-05
  • 2019-01-24
  • 1970-01-01
  • 2017-04-14
  • 2013-06-29
  • 2018-08-03
  • 2017-06-08
  • 1970-01-01
相关资源
最近更新 更多