我有一个看起来像这样的DF(从记帐软件中收集)。
Serial || Date || Particulars || Price -------------------------------------- 1 || 0308 || Andrew || 100 2 || NaN || Gloves || NaN 3 || 0408 || Johnson || 50 4 || NaN || Wicket || NaN
我想合并两个连续的行,并使用第二行“特殊”值创建一个新列“产品”。 预期的输出应类似于---
Serial || Date || Particulars || Price || Product ------------------------------------------------- 1 || 0308 || Andrew || 100 || Gloves 3 || 0408 || Johnson || 50 || Wicket
如何用熊猫实现这一目标?
答案 0 :(得分:4)
这些答案基于数据框的格式,该格式始终显示遵循与OP所提供的相同模式的成对的行。第一行显示一个人,第二行显示产品和日期,价格列为NaN。
shift
和dropna
df.assign(Product=df.Particulars.shift(-1)).dropna()
Serial Date Particulars Price Product
0 1 308.0 Andrew 100.0 Gloves
2 3 408.0 Johnson 50.0 Wicket
join
完全相同但又不同
df.join(df.Particulars.shift(-1).rename('Product')).dropna()
每个请求
df.Particulars.shift(-1)
将“详细信息”列的所有成员都移回一行
0 Gloves
1 Johnson
2 Wicket
3 NaN
Name: Particulars, dtype: object
当我将其分配给现有数据框df.assign(Product=df.Particulars.shift(-1))
时,它将添加一个新名称'Product'
的列,其中的值是移位的细节。
Serial Date Particulars Price Product
0 1 308.0 Andrew 100.0 Gloves
1 2 NaN Gloves NaN Johnson
2 3 408.0 Johnson 50.0 Wicket
3 4 NaN Wicket NaN NaN
剩下的就是使用NaN
值删除行,我们已经在上面给出了内容。
如果我每隔一行进行切片,则无需依赖dropna
df.assign(Product=df.Particulars.shift(-1))[::2]
或更简洁
df[::2].assign(Product=[*df.Particulars[1::2]])
这是我想到的第一个方法,这很重要
i = np.flatnonzero(df.Price.notna())
j = i + 1
df.iloc[i].assign(Product=df.iloc[j].Particulars.values)
Serial Date Particulars Price Product
0 1 308.0 Andrew 100.0 Gloves
2 3 408.0 Johnson 50.0 Wicket
答案 1 :(得分:1)
丑陋但简单:
ans = df[~pd.isna(df.Date)].copy()
ans['product'] = df[pd.isna(df.Date)].Particulars.values
Date Particulars Price product
Serial
1 308.0 Andrew 100.0 Gloves
3 408.0 Johnson 50.0 Wicket
答案 2 :(得分:1)
尝试shift
并删除偶数行:
df['Product'] = df['Particulars'].shift(-1)
df = df.loc[0:len(df):2]