2

在 Pandas (v0.8.0) 中DataFrame,我想用另一列覆盖一个列。

下面的代码抛出列出的错误。

实现这一目标的有效替代方法是什么?

df = DataFrame({'a' : range(0,7),
'b' : np.random.randn(7),
'c' : np.random.randn(7),
'd' : np.random.randn(7),
'e' : np.random.randn(7),
'f' : np.random.randn(7),
'g' : np.random.randn(7)})

# overwrite cols
df.ix[:,'b':'d'] = df.ix[:, 'e':'g']

Traceback (most recent call last):
File "C:\Python27\lib\site-packages\pandas\core\indexing.py", line 68, in __setitem__
self._setitem_with_indexer(indexer, value)
File "C:\Python27\lib\site-packages\pandas\core\indexing.py", line 98, in   _setitem_with_indexer
raise ValueError('Setting mixed-type DataFrames with '
ValueError: Setting mixed-type DataFrames with array/DataFrame pieces not yet supported

已编辑

作为一种排列,我怎么还能指定要设置的行的子集

df.ix[df['a'] < 3, 'b':'d'] = df.ix[df['a'] < 3, 'e':'g']
4

1 回答 1

6

问题是 using.ix[]返回一个视图到该 DataFrame 子集的实际内存对象,而不是由其内容组成的新 DataFrame。

而是使用

# The left-hand-side does not use .ix, since we're assigning into it.
df[['b','c']] = df.ix[:,'e':'f'].copy()

请注意,.copy()如果您打算使用.ix来进行切片,则需要,否则它会将列“b”和“c”设置为内存中与列“e”和“f”相同的对象,这看起来不像你想在这里做什么。

或者,为了避免担心复制你,你可以这样做:

df[['b','c']] = df[['e','f']]

如果索引的便利性对您很重要,模拟这种效果的一种方法是编写您自己的函数:

def col_range(df, col1, col2): 
    return list(dfrm.ix[dfrm.index.values[0],col1:col2].index)

现在您可以执行以下操作:

df[col_range(df,'b','d')] = df.ix[:,'e':'g'].copy()

注意:在定义中col_range我使用了第一个索引,它将选择数据框的第一行。我这样做是因为仅仅为了选择一系列列而查看整个数据框似乎很浪费,而一行可能无关紧要。由于以这种方式切片会产生一个系列,因此提取列的方法是实际获取索引,并将它们作为列表返回。

为额外的行切片请求添加:

要在赋值中指定一组行,您可以使用.ix,但您只需在右侧指定一个值矩阵。在右侧有一个子数据帧的结构会导致问题。

df.ix[0:4,col_range(df,'b','d')] = df.ix[0:4,'e':'g'].values

例如,您可以[0:4][df.index.values[i]:df.index.values[j]][df.index.values[i] for i in range(N)]什至用逻辑值替换 ,例如[df['a']>5]仅获取“a”列超过 5 的行。

您希望列 'a' 大于 5 且列 'e' 小于 10 的逻辑索引示例的完整切片可能如下所示:

import numpy as np
my_rows = np.logical_and(df['a'] > 5), df['e'] < 10)
df.ix[my_rows,col_range(df,'b','d')] = df.ix[my_rows,'e':'g'].values

在许多情况下,您不需要使用.ix左侧的 (我建议不要使用它,因为它只在某些情况下有效,而在其他情况下无效)。例如,类似:

df["A"] = np.repeat(False, len(df))
df["A"][df["B"] > 0] = True

将按原样工作,无需特别.ix识别条件为真的行。当.ix右边的事情很复杂时,左边似乎需要。

于 2012-07-15T22:00:05.593 回答