我已经使用iterrows()做到了这一点,但是希望有一种更快,更优雅的方法来达到预期的效果。
问题陈述:
我在数据帧(product1, product2, ...)
的列(df_orders)
的子集中有几行NaN和notnull值。我想获取此子集中的每个非null值,并创建一个新列,其中包含从第一行一直到最后一行的每个值。
示例: 创建一个包含所有订购产品的列。
>>> df_orders = pd.read_csv('orders.csv')
>>> df_orders
OrderNo CustName Product1 Product2 Product3 Product4 Product5
0 20043 Sanjay Singh 131 320 320 131 nan
1 20042 William Sonoma 420 420 131 320 511
2 20041 Maria Alonso 320 420 320 nan nan
3 20040 Jim Beam 511 131 nan nan nan
4 20039 Gunter Grass 320 131 131 131 nan
5 20038 Billy Joe Bob 420 511 511 nan nan
6 20037 Cynthia Silvia Stout 55 12 131 55 12
7 20036 Alan Ginsburg 131 320 320 12 nan
8 20035 Ronald McDonald 131 131 511 nan nan
我正在寻找的结果:
创建一个名为df_product_list的新数据框。从df_orders中的第一行开始,在df_product_list中为每个非空产品列值创建一个新行。
由于来自Sanjay Singh的订单排在第一位,并且product列中有四个非空值,因此df_product_list的前四行将为131、320、320和131。
>>> df_product_list
ProdCode
0 131
1 320
2 320
3 131
4 420
5 420
6 131
7 320
8 511
9 320
10 420
11 320
12 511
13 131
14 320
15 131
16 131
17 131
...
...
答案 0 :(得分:2)
让我们尝试filter
和stack
吗?
pd.Series(df.filter(like='Product').stack().values, name='product_list')
0 131.0
1 320.0
2 320.0
3 131.0
4 420.0
5 420.0
...
为了提高性能,您可能希望在numpy空间中操作,并使用np.isnan
丢弃NaN(DataFrame.stack
可以这样做,但是成本要高得多)。
arr = df.filter(like='Product').values.ravel()
pd.Series(arr[~np.isnan(arr)].astype(np.int), name='product_list')
0 131.0
1 320.0
2 320.0
3 131.0
4 420.0
5 420.0
...