当前位置: 首页 > 知识库问答 >
问题:

熊猫数据框循环某些列的所有值

章永安
2023-03-14

使用pandas dataframe假设我有如下结构相似的数据帧:

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,则选择“a_n”,值=a对应于“a_Cho”的值如果“a_Cho”=false,则移动到下一步
  • 如果“b_Cho”=true,则选择“b_n”,值=b表示“b_Cho”的对应值,如果“b_Cho”=false,则移动到下一步
  • 如果“c_Cho”=真,则选择“c_n”,值=c表示“c_Cho”的对应值,如果“c_Cho”=假,则移动到下一步
  • 如果“x_Cho”=false,则选择value并选择“Invalide”

共有1个答案

白祺然
2023-03-14

谢谢你更新你的问题。在您编辑之后,我相信.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\u index=True选项传递到.concat

这更接近你想要的吗?

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

我的印象是,你的问题可能类似于这个使用pd.melt的问题。

你的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将其重新构造为两列,一列为“column names”列,另一列为“column values”列,如您在问题中所述。

上面的示例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示例,以及您希望最终结果是什么样的示例?它可以是一个简化的或“模拟”的例子。

 类似资料:
  • 问题内容: 我有一个名称为的csv文件。我打开并使用以下方法创建了一个熊猫: 其中,是字符串对象的python列表。示例(实际列表的长度为22): 在ipython提示符下,如果我键入并按Enter键,则不会获得带有列和值的数据框,如Pandas网站上的示例所示。相反,我获得有关数据框的信息。我得到: 如果我键入,那么我确实会获得该列的预期值。我有两个问题: (1)在pandas网站上的示例中(例

  • 问题内容: 我想统计数据框中某些单词出现的次数。我知道使用“ str.contains” 目前,我正在使用上面的代码。是否有一种匹配正则表达式并获得出现次数的方法?就我而言,我有一个大的数据框,我想匹配大约100个字符串。 问题答案: 更新:原始答案计算包含子字符串的行。 要计算子字符串的所有出现次数,可以使用: 该方法接受正则表达式: 例如: 要计算出现的次数,您可以对布尔系列求和:

  • 问题内容: 我正在寻找一种方法来反向旋转数据框。据我所知,pandas提供了一种pivot或pivot_table方法将EAV df转换为“普通”方法。但是,还有一种方法可以做逆运算吗? 所以给定数据框: 我想将其转换为(EAV模型): 这样做最有效的方法是什么? 问题答案: 假设是索引,将执行以下操作: 如果不是索引,请像这样设置:

  • 这是一个非常基本的问题,我似乎找不到答案。 我有一个这样的数据帧,叫做df: 然后我从df中提取所有行,其中列'B'的值为'B.2'。我将这些结果分配给df_2。 df_2变成: 然后,我将列B中的所有值复制到名为D的新列中。使df_2成为: 当我执行这样的任务时: 我得到以下警告: 试图在数据帧切片的副本上设置值。尝试使用。loc[row\u indexer,col\u indexer]=改为v

  • 我正在尝试制作一个数据帧,以便可以轻松地将其发送到CSV,否则我必须手动执行此过程。。 我希望这是我的最终输出。每个人都有一个月和年的组合,从2014年1月1日开始,一直到2016年1月12日: 到目前为止的代码: 当我尝试循环创建数据帧时,它要么不工作,要么出现索引错误(因为不匹配列表),我不知所措。 我已经做了一点很好的搜索,并找到了以下一些类似的链接,但我不能反向工程的工作,以适应我的情况。

  • 我想使用两列作为行ID,同时计算基于时间的分组。请看下图: 转化成这样: 正在发生的是,X在时间10发生了0次,但在15和23发生了1次。 Y在10点钟发生了3次,但在15和23没有。等等。