0

シリーズ (条件によって論理的にインデックス付けされた) からスライス ビューを取得し、それを処理してから、その論理的にインデックス付けされたスライスに結果を割り当てようとしています。代入の LHS と RHS はインデックスが一致する Series ですが、代入は不明な理由で最終的にスカラーになります (下部を参照)。希望の配属先を取得するには?(関連するものについては、SOとpandas 0.11.0のドキュメントを確認しました)。

import numpy as np
import pandas as pd

# A dataframe with sample data and some boolean conditional
df = pd.DataFrame(data={'x': range(1,20)})
df['cond'] = df.x.apply(lambda xx: ((xx%3)==1) )

# Create a new col and selectively assign to it... elsewhere being NaN...
df['newcol'] = np.nan
# This attempted assign to a view of the df doesn't work (in reality the RHS expression would actually be a return value from somefunc)
df.ix[df.cond, df.columns.get_loc('newcol')] = 2* df.ix[df.cond, df.columns.get_loc('x')]
# yet a scalar assign does...
df.ix[df.cond, df.columns.get_loc('newcol')] = 99.
# Likewise bad trying to use -df.cond as the logical index:
df.ix[-df.cond, df.columns.get_loc('newcol')] = 2* df.ix[-df.cond, df.columns.get_loc('x')]

現在、私は愚かなスカラー割り当てを取得しています:

>>> df.ix[-df.cond, df.columns.get_loc('newcol')] = 2* df.ix[-df.cond, df.columns.get_loc('x')]
>>> df
     x   cond  newcol
0    1   True     NaN
1    2  False       4
2    3  False       4
3    4   True     NaN
4    5  False       4
5    6  False       4
6    7   True     NaN
7    8  False       4
8    9  False       4
9   10   True     NaN
10  11  False       4
11  12  False       4
12  13   True     NaN
13  14  False       4
14  15  False       4
15  16   True     NaN
16  17  False       4
17  18  False       4
18  19   True     NaN
4

2 に答える 2

1
In [21]: df = pd.DataFrame(data={'x': range(1,20)})

In [22]: df['cond'] = df.x.apply(lambda xx: ((xx%3)==1) )

In [23]: df
Out[23]: 
     x   cond
0    1   True
1    2  False
2    3  False
3    4   True
4    5  False
5    6  False
6    7   True
7    8  False
8    9  False
9   10   True
10  11  False
11  12  False
12  13   True
13  14  False
14  15  False
15  16   True
16  17  False
17  18  False
18  19   True

In [24]: df['newcol'] = 2*df.loc[df.cond, 'x']

In [25]: df
Out[25]: 
     x   cond  newcol
0    1   True       2
1    2  False     NaN
2    3  False     NaN
3    4   True       8
4    5  False     NaN
5    6  False     NaN
6    7   True      14
7    8  False     NaN
8    9  False     NaN
9   10   True      20
10  11  False     NaN
11  12  False     NaN
12  13   True      26
13  14  False     NaN
14  15  False     NaN
15  16   True      32
16  17  False     NaN
17  18  False     NaN
18  19   True      38


In [10]: def myfunc(df_):
   ....:     return 2 * df_
   ....: 

 In [26]: df['newcol'] = myfunc(df.ix[df.cond, df.columns.get_loc('newcol')])

In [27]: df
Out[27]: 
     x   cond  newcol
0    1   True       4
1    2  False     NaN
2    3  False     NaN
3    4   True      16
4    5  False     NaN
5    6  False     NaN
6    7   True      28
7    8  False     NaN
8    9  False     NaN
9   10   True      40
10  11  False     NaN
11  12  False     NaN
12  13   True      52
13  14  False     NaN
14  15  False     NaN
15  16   True      64
16  17  False     NaN
17  18  False     NaN
18  19   True      76
于 2013-06-03T02:09:06.827 に答える
0

この回避策を見つけました:

tmp = pd.Series(np.repeat(np.nan, len(df)))
tmp[-cond] = 2* df.loc[df.cond, 'x']
df['newcol'] = tmp

奇妙なことに、以下は時々機能します (スライスをシリーズ全体に割り当てます) (ただし、より複雑な RHS with では失敗しますAssertionError: Length of values does not match length of index)

(パンダのドキュメントによると、RHS シリーズのインデックスは、少なくとも LHS がデータフレームの場合は LHS に合わせられるはずですが、シリーズの場合はそうではありませんか?これはバグですか?)

>>> df['newcol'] = 2* df.loc[df.cond, 'x']
>>> df
     x   cond  newcol
0    1   True       2
1    2  False     NaN
2    3  False     NaN
3    4   True       8
4    5  False     NaN
5    6  False     NaN
6    7   True      14
7    8  False     NaN
8    9  False     NaN
9   10   True      20
10  11  False     NaN
11  12  False     NaN
12  13   True      26
13  14  False     NaN
14  15  False     NaN
15  16   True      32
16  17  False     NaN
17  18  False     NaN
18  19   True      38

Jeffさん、次の場合に df['newcol'] (これはビューではなくコピーであるはずですよね?) に割り当てることができるのは奇妙なことです。

df['newcol'] = 2* df.loc[df.cond, 'x']

ただし、fn からの RHS で同じことを行う場合は異なります。

def myfunc(df_):
    """Some func transforming and returning said Series slice"""
    return 2* df_

df['newcol'] = myfunc( df.ix[df.cond, df.columns.get_loc('newcol')] )
于 2013-06-03T01:20:26.047 に答える