熊猫Multiindex:我做错了什么?

时间:2014-10-06 16:55:33

标签: python numpy pandas cluster-analysis

我有一个程序,我有一个大的pandas数据框的成对交互(在行中),我随机遍历。每个连续步骤的选项列表从整个数据框中缩小两列中的特定值,所以基本上,

df_options = df[(df.A == x) & (df.B == y)]

我让这个东西使用上面的语法,但似乎在速度方面(这是限制性的)将Af索引为d,这样会是一个好主意:

df.sort(['A', 'B'], inplace=True)
df.index = df.index.rename('idx')
df = df.set_index(['A', 'B'], drop=False, append=True, verify_integrity=True)

(请注意我将原始索引保持为' idx'因为这就是我记录随机漫步和访问特定行的方式)
所以我先用原来的df_options代码替换了原来的df_options代码 df.xs((x, y), level=('A', 'B'))
在遇到问题之后,
df.loc(axis=0)[:,A,B]

此外,在我需要特定值的地方,原始语法从

更改
df_options.loc[new, 'sim']

df_options.xs(new, level='idx')['sim'].values[0]

df_options.loc(axis=0)[new,:,:]['sim'].values[0]

(" new"是随机选择的df的下一个索引,而' sim'是一对成对相似度得分。)

当我试图让这个工作时,我不断收到错误,例如'...not hashable'AttributeError: 'Int64Index' object has no attribute 'get_loc_level

这让我想到了标题中的问题:我做错了什么?更具体地说:
1)多索引真的有可能像我想的那样加速这个过程吗? 2)如果是这样,在这里使用的正确习语是什么(感觉就像我用.xs和.loc建立了一条小溪),
3)或者我应该使用像raw numpy这样的其他东西吗?

编辑在使用代码创建示例的过程中,我设法让它运行起来。我会说我必须跳过一些尴尬的箍,比如.values[0]row.p2.values[0]中的df.index[rand_pair][0][0]

回应杰夫: 大熊猫0.14.1

df.info()
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 561567 entries, (0, 0, 003) to (561566, 26127, 011)
Data columns (total 14 columns):
p1              561567 non-null int64
smp1            561567 non-null object
rt1             561567 non-null float64
cas1            561567 non-null object
sim1            561567 non-null float64
p2              561567 non-null int64
smp2            561567 non-null object
rt2             561567 non-null float64
cas2            561567 non-null object
sim2            561567 non-null float64
nlsim1          561567 non-null float64
sum_spec_sq1    561567 non-null float64
sum_spec_sq2    561567 non-null float64
sum_s1s2        561567 non-null float64
dtypes: float64(8), int64(2), object(4)

注意:&#34; p1&#34;,&#34; smp2&#34;和&#34; nlsim1&#34;对应于&#34; A&#34; &#34; B&#34;和&#34; sim&#34;在上面的问题中。 足够的数据可以走几步:

df = pd.DataFrame({u'nlsim1': {174513: 0.8782, 270870: 0.9461, 478503: 0.8809},
 u'p1': {174513: 8655, 270870: 13307, 478503: 22276},
 u'p2': {174513: 13307, 270870: 22276, 478503: 2391},
 u'smp1': {174513: u'007', 270870: u'010', 478503: u'016'},
 u'smp2': {174513: u'010', 270870: u'016', 478503: u'002'}})
df.index = df.index.rename('idx')
df = df.set_index(['p1', 'smp2'], drop=False, append=True, verify_integrity=True)

def weighted_random_choice():
    options = df_options.index.tolist()
    tot = df_options.nlsim1.sum()
    options_weight = df_options.nlsim1 / tot
    return np.random.choice(options, p=list(options_weight))

开始散步:

samples = set([c for a, b, c in df.index.values])
df_numbered = range(df.shape[0])
#rand_pair = random.sample(df_numbered, 1)
rand_pair = [0]
path = [df.index[rand_pair][0][0]]

walk(迭代它):

row = df.loc[path[-1],:,:]
p = row.p2.values[0]
smp = row.smp2.values[0]
print p, smp
samples.discard(smp)
print sorted(list(samples))
pick_sample = random.sample(samples, 1)[0]
print pick_sample
df_options = df.xs((p, pick_sample), level=('p1', 'smp2'))
if df_options.shape[0] < 1:
    print "out of options, stop iterating"
    print "path=", path
else:
    print "# options: ", df_options.shape[0]
    new = weighted_random_choice()
    path.append(new)
    print path
    print "you should keep going"

输出,第1步:

13307 010
[u'002', u'016']
016
# options:  1
[174513, 270870]
you should keep going

第二步:

22276 016
[u'002']
002
# options:  1
[174513, 270870, 478503]
you should keep going

预期的第三步错误b / c样本用完了。

1 个答案:

答案 0 :(得分:0)

嗯,简单的解决方法是使用数据框的两个副本,原始数据和另一个由'A'和'B'索引的副本:

dfi = df.set_index(['A', 'B'])

通过更改“选择特定的A,B”范例

df_options = df[(df.A == x) & (df.B == y)]

df_options = dfi.loc(axis=0)[x, y]

我的速度提高了5倍。它应该以df的大小更好地扩展。