【问题标题】:Filtering rows from pandas dataframe using concatenated strings使用连接字符串从熊猫数据框中过滤行
【发布时间】:2013-07-09 22:09:06
【问题描述】:

我有一个 pandas 数据框和一个 pandas 标识符系列,并希望从数据框中过滤出与该系列中的标识符相对应的行。要从数据框中获取标识符,我需要连接它的前两列。我尝试了各种过滤方法,但到目前为止似乎没有任何效果。这是我尝试过的:

1) 我尝试在数据框中添加一列布尔值,如果该行对应于其中一个标识符,则为 true,否则为 false(希望之后能够使用新列进行过滤):

df["isInAcids"] = (df["AcNo"] + df["Sortcode"]) in acids

在哪里

acids

是包含标识符的系列。

但是,这给了我一个

TypeError: unhashable type

2) 我尝试使用 apply 函数进行过滤:

df[df.apply(lambda x: x["AcNo"] + x["Sortcode"] in acids, axis = 1)]

这不会给我一个错误,但数据框的长度保持不变,所以它似乎没有过滤任何东西。

3) 我添加了一个新列,其中包含连接的字符串/标识符,然后尝试过滤(参见Filter dataframe rows if value in column is in a set list of values):

df["ACIDS"] = df["AcNo"] + df["Sortcode"]
df[df["ACIDS"].isin(acids)]

但同样,数据框没有改变。

我希望这是有道理的......

有什么建议我可能会出错吗? 谢谢, 安妮

【问题讨论】:

  • 您能否发布一个小样本,说明您的dataframeseries 以及您期望的结果是什么样的?
  • 这些操作不是就地的,所以除非你明确告诉它,否则数据框不会改变(这是一件好事)。
  • 嗨,安迪,非常感谢,如果我在第三个解决方案中添加 df = ... 就可以了。

标签: python pandas


【解决方案1】:

我认为您要求的是以下内容:

In [1]: other_ids = pd.Series(['a', 'b', 'c', 'c'])

In [2]: df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': ['a', 'b', 'c', 'f']})

In [3]: df
Out[3]: 
  ids  vals
0   a     1
1   b     2
2   c     3
3   f     4

In [4]: other_ids
Out[4]: 
0    a
1    b
2    c
3    c
dtype: object

在这种情况下,系列 other_ids 将类似于您的系列 acids。我们只想选择dfid 在系列other_ids 中的那些行。为此,我们将使用dataframe 的方法.isin()

In [5]: df.ids.isin(other_ids)
Out[5]: 
0     True
1     True
2     True
3    False
Name: ids, dtype: bool

这给出了一列我们可以索引的布尔值:

In [6]: df[df.ids.isin(other_ids)]
Out[6]: 
  ids  vals
0   a     1
1   b     2
2   c     3

这与您在第三次尝试时所做的很接近。发布数据框示例后,我可以编辑此答案(如果它还不起作用)。

多读一点,您可能会遇到麻烦,因为您在 df 中有两列是您的 id? Dataframe 没有 isin 方法,但我们可以通过以下方式解决这个问题:

In [26]: df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': ['a', 'b', 'f', 'f'], 
'ids2': ['e', 'f', 'c', 'f']})

In [27]: df
Out[27]: 
  ids ids2  vals
0   a    e     1
1   b    f     2
2   f    c     3
3   f    f     4

In [28]: df.ids.isin(ids) + df.ids2.isin(ids)
Out[28]: 
0     True
1     True
2     True
3    False
dtype: bool

True 与 1 类似,False 与 0 类似,因此我们将两个 isins() 中的两个布尔系列相加得到类似 OR 的操作。然后像之前一样,我们可以索引到这个布尔系列:

In [29]: new = df.ix[df.ids.isin(ids) + df.ids2.isin(ids)]

In [30]: new
Out[30]: 
  ids ids2  vals
0   a    e     1
1   b    f     2
2   f    c     3

【讨论】:

  • 我认为这个问题的主要困惑是这些操作没有到位(即您需要设置df = df[df.ids.isin(other_ids)]
  • 我认为是对的。另一个问题可能是她有两列ids,而我有一个。 dataframe 没有带有 orand 等选项的 isin() 方法是否有原因?
  • 不,应该没问题。我认为执行 or/and 之后更有效,因此 pandas 做出了您应该这样做的执行决定。
  • 我将打开一个 GH 问题。虽然没有关于 PR 的承诺。我真的需要回去工作了:)
  • 嘿汤姆,非常感谢这个例子。我已将其扩展到我需要的内容:试试new_ids = pd.Series(["a1,c3"])df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': ['a', 'b', 'c', 'f'], 'stuff':["insert", "whatever","you","fancy"]})。我想通过在“ids”和“vals”列中附加字符串来过滤行以匹配new_ids中的内容......最好不要像我目前所做的那样先创建一个额外的列。
猜你喜欢
  • 2023-03-14
  • 2015-09-24
  • 2018-10-04
  • 2022-07-01
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
相关资源
最近更新 更多