我有一个程序,我有一个大的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样本用完了。
答案 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的大小更好地扩展。