这个方法怎么样?我稍微改了一下你的数据,以便呼叫出售 4 张门票。
我们使用一个适当大小的 np.ones() 辅助数组,然后关键代码行是:
a[np.arange(a.shape[1])[:] > a[:,0,np.newaxis]] = 0
。
我在这里看到了这种技术:
numpy - update values using slicing given an array value。
然后只需调用
.stack()
和一些基本过滤即可完成。
d = {'1': ['20', 'NYC', '2'], '2': ['30', 'NYC', '2'], '3': ['5', 'NYC', '2'], \
'4': ['300', 'LA', '2'], '5': ['30', 'LA', '4'], '6': ['100', 'LA', '2']}
columns=['Price', 'City', 'Quantity']
df = pd.DataFrame.from_dict(data=d, orient='index')
df.columns = columns
df['Quantity'] = df['Quantity'].astype(int)
my_ones = np.ones(shape=(len(df),df['Quantity'].max()))
df_my_ones = pd.DataFrame(data =my_ones,index = df.index)
df = df.join(df_my_ones)
看起来像这样:
Price City Quantity 0 1 2 3
1 20 NYC 2 1 1 1 1
3 5 NYC 2 1 1 1 1
2 30 NYC 2 1 1 1 1
5 30 LA 4 1 1 1 1
4 300 LA 2 1 1 1 1
现在把“Quantity”列和“ones”合并到一个numpy数组中。
a = df.iloc[:,2:].values
这是聪明的部分。
a[np.arange(a.shape[1])[:] > a[:,0,np.newaxis]] = 0
并且重新分配回到df中。
df.iloc[:,2:] = a
现在df的样子如下,注意我们已经将Quantity后面的数字设为零:
Price City Quantity 0 1 2 3
1 20 NYC 2 1 1 0 0
3 5 NYC 2 1 1 0 0
2 30 NYC 2 1 1 0 0
5 30 LA 4 1 1 1 1
4 300 LA 2 1 1 0 0
df.set_index(['Price','City','Quantity'],inplace=True)
df = df.stack().to_frame()
df.columns = ['sale_flag']
df.reset_index(inplace=True)
print df[['Price','City', 'Quantity']][df['sale_flag'] !=0]
print df
该功能会生成以下内容:
Price City Quantity
0 20 NYC 2
1 20 NYC 2
4 5 NYC 2
5 5 NYC 2
8 30 NYC 2
9 30 NYC 2
12 30 LA 4
13 30 LA 4
14 30 LA 4
15 30 LA 4
16 300 LA 2
17 300 LA 2