我有一个交易数据框。每行代表两个项目的交易(将其视为2个事件票据或其他事务的交易)。我想根据销售数量复制每一行。
以下是示例代码:
# dictionary of transactions
d = {'1': ['20', 'NYC', '2'], '2': ['30', 'NYC', '2'], '3': ['5', 'NYC', '2'], \
'4': ['300', 'LA', '2'], '5': ['30', 'LA', '2'], '6': ['100', 'LA', '2']}
columns=['Price', 'City', 'Quantity']
# create dataframe and rename columns
df = pd.DataFrame.from_dict(data=d, orient='index')
df.columns = columns
这会产生一个看起来像这样的数据框
Price City Quantity
20 NYC 2
30 NYC 2
5 NYC 2
300 LA 2
30 LA 2
100 LA 2
因此,在上面的情况中,每行将转换为两个重复的行。如果'数量' column为3,然后该行将转换为三个重复的行。
答案 0 :(得分:8)
首先,我使用整数而不是文本重新创建数据。我也改变了数量,以便人们可以更容易地理解问题。
d = {1: [20, 'NYC', 1], 2: [30, 'NYC', 2], 3: [5, 'SF', 3],
4: [300, 'LA', 1], 5: [30, 'LA', 2], 6: [100, 'SF', 3]}
columns=['Price', 'City', 'Quantity']
# create dataframe and rename columns
df = pd.DataFrame.from_dict(data=d, orient='index').sort_index()
df.columns = columns
>>> df
Price City Quantity
1 20 NYC 1
2 30 NYC 2
3 5 SF 3
4 300 LA 1
5 30 LA 2
6 100 SF 3
我使用嵌套列表理解结构创建了一个新的DataFrame。
df_new = pd.DataFrame([df.ix[idx]
for idx in df.index
for _ in range(df.ix[idx]['Quantity'])]).reset_index(drop=True)
>>> df_new
Price City Quantity
0 20 NYC 1
1 30 NYC 2
2 30 NYC 2
3 5 SF 3
4 5 SF 3
5 5 SF 3
6 300 LA 1
7 30 LA 2
8 30 LA 2
9 100 SF 3
10 100 SF 3
11 100 SF 3
答案 1 :(得分:3)
这种方法怎么样?我稍微改变了你的数据,以便出售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)
# make a ones array
my_ones = np.ones(shape=(len(df),df['Quantity'].max()))
# turn my_ones into a dataframe same index as df so we can join it to the right hand side. Plenty of other ways to achieve the same outcome.
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列,将其变为numpy数组
a = df.iloc[:,2:].values
这是聪明的一点
a[np.arange(a.shape[1])[:] > a[:,0,np.newaxis]] = 0
并重新分配给df。
df.iloc[:,2:] = a
现在df看起来如下,请注意我们如何将数量设置为零,数量为:
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
答案 2 :(得分:0)
使用repeat
df.loc[df.index.repeat(df.Quantity)]
Out[448]:
Price City Quantity
1 20 NYC 2
1 20 NYC 2
2 30 NYC 2
2 30 NYC 2
3 5 NYC 2
3 5 NYC 2
4 300 LA 2
4 300 LA 2
5 30 LA 2
5 30 LA 2
6 100 LA 2
6 100 LA 2