pandas:迭代过滤DataFrame的行

时间:2013-08-29 21:11:14

标签: python pandas dataframe

假设我有DataFrame这样,

df = pd.DataFrame([['x', 1, 2], ['x', 1, 3], ['y', 2, 2]], 
                  columns=['a', 'b', 'c'])

要选择c == 2a == 'x'的所有行,我可以执行类似的操作,

df[(df['a'] == 'x') & (df['c'] == 2)]

或者我可以通过制作临时变量进行迭代改进,

df1 = df[df['a'] == 'x']
df2 = df1[df1['c'] == 2]

有没有办法对行进行迭代优化?

(
  df
  .refine(lambda row: row['a'] == 'x')     # this method doesn't exist
  .refine(lambda row: row['c'] == 2)
)

2 个答案:

答案 0 :(得分:1)

虽然这不是现在的解决方案,但在pandas版本0.13中你可以做到

df.query('a == "x"').query('c == 2')

实现你想要的目标。

你也可以做到

df['a == "x"']['c == 2']

df['a == "x" and c == 2']

有什么问题
df[(df.a == 'x') & (df.c == 2)]

直到0.13?

答案 1 :(得分:0)

如果您有多个条款;在运行之前您不知道的数量,您可以执行以下操作。我并不是说这是实现目标的一种美妙方式,但我无法看到Pandas 0.14.1的另一种选择:

df = pd.DataFrame([['x', 1, 2], ['x', 1, 3], ['y', 2, 2]],
                  columns=['a', 'b', 'c'])

conditions = {'a': 'x', 'c': 2}

def esc(term):
    if isinstance(term, str):
        return '"%s"' % term
    return str(term)

q_parts = ["%s == %s" % (k, esc(v)) for k, v in conditions.items()]
q = ' and '.join(q_parts)

print df.query(q)

当然,esc函数或更广泛的代码片段需要进一步扩展以处理逻辑NOT,x是in(x,y,z)等...