Python:基于另一个列和行的条件函数创建新列

时间:2019-02-24 03:59:39

标签: python pandas

我正在尝试根据不同列和行中的数据生成一些新列。例如,采用以下系列:

df = pd.Series(['Fruit[edit]','Apple','Orange','Banana','Vegetable[edit]','Celery','Beans','Kale'])

0        Fruit[edit]
1              Apple
2             Orange
3             Banana
4    Vegetable[edit]
5             Celery
6              Beans
7               Kale

我从一个系列开始,其中带有“ [edit]”的元素代表类别,其余的是属于该类别的项目的名称。我想创建两个新列,一列显示“类别”(即水果或蔬菜),另一列显示“名称”列,显示属于该类别的项目。

最终结果应如下所示:

Desired Result

    Category    Name
0   Fruit       Apple
1   Fruit       Orange
2   Fruit       Banana
3   Vegetable   Celery
4   Vegetable   Beans
5   Vegetable   Kale

在阅读本系列文章时,我希望代码识别一个新类别(即,以“ [edit]”结尾的元素,并将其存储为项目的更新类别,直到达到较新的类别。

3 个答案:

答案 0 :(得分:3)

使用:

#if necessary convert Series to DataFrame 
df = df.to_frame('Name')
#get rows with edit
mask = df['Name'].str.endswith('[edit]')
#remove edit
df.loc[mask, 'Name'] = df['Name'].str[:-6]
#create Category column
df.insert(0, 'Category', df['Name'].where(mask).ffill())
#remove rows with same values in columns
df = df[~mask].copy()
print (df)
    Category    Name
1      Fruit   Apple
2      Fruit  Orange
3      Fruit  Banana
5  Vegetable  Celery
6  Vegetable   Beans
7  Vegetable    Kale

答案 1 :(得分:2)

这可能很难看,但是可以做到:

df = pd.DataFrame(df) #since df is a series
df['Name']=df.groupby(df[0].str.contains('edit').cumsum())[0].apply(lambda x: x.shift(-1))
df=df.dropna().rename(columns={0:'Category'})
df.loc[~df.Category.str.contains('edit'),'Category']=np.nan
df.Category=df.Category.ffill()
df.Category=df.Category.str.split("[").str[0]
print(df)

    Category    Name
0      Fruit   Apple
1      Fruit  Orange
2      Fruit  Banana
4  Vegetable  Celery
5  Vegetable   Beans
6  Vegetable    Kale

答案 2 :(得分:2)

您可以使用str.extract根据关键字的存在来提取组,

new_df = df.str.extract('(?P<Category>.*\[edit\])?(?P<Name>.*)')\
.replace('\[edit\]', '', regex = True).ffill()\
.replace('', np.nan).dropna()

    Category    Name
1   Fruit   Apple
2   Fruit   Orange
3   Fruit   Banana
5   Vegetable   Celery
6   Vegetable   Beans
7   Vegetable   Kale