Панды Использование оператора If для перехода строка за строкой

1

Я не был уверен, что это лучший титул для этого, если у кого-то есть лучшая идея для титула, я готов к советам.

Скажем, у меня есть кадр данных, который выглядит так:

df2

             A     section
0      <fruit>
1        apple
2       orange
3         pear
4   watermelon
5     </fruit>
6  <furniture>
7        chair
8         sofa
9        table
10        desk
11 </furniture>

То, что я хочу, это dataframe, который выглядит так:

             A     section
0      <fruit>       fruit
1        apple       fruit
2       orange       fruit
3         pear       fruit
4   watermelon       fruit
5     </fruit>       fruit
6  <furniture>   furniture
7        chair   furniture
8         sofa   furniture
9        table   furniture
10        desk   furniture
11 </furniture>  furniture

Есть ли способ сделать это? Я думал об использовании инструкции if, чтобы идти по строке, но у меня были проблемы с логической логикой, когда я это делал.

Редактировать # 1:

Это решение, опубликованное ниже, решает мою проблему.

Решение:

df['section']=pd.Series(np.where(df.A.str.contains('<'),df.A.str.replace('<|>|/',''),np.nan)).ffill()

Что делать, если у меня есть данные, которые выглядят так? Я хотел бы получить тот же результат.

                                       A          section
0                                 <fruit>
1                <fruit_1>apple</fruit_1>
2               <fruit_2>orange</fruit_2>
3                 <fruit_3>pear</fruit_3>
4           <fruit_4>watermelon</fruit_4>
5                                </fruit>
6                             <furniture>
7        <furniture_1>chair</furniture_1>
8         <furniture_2>sofa</furniture_2>
9        <furniture_3>table</furniture_3>
10        <furniture_4>desk</furniture_4>
11                           </furniture>
Теги:
pandas
python-3.x

2 ответа

3
Лучший ответ

Использование IIUC contains поиск строки, а np.where присваивает значение, затем используя ffill fill np.nan

df['section']=pd.Series(np.where(df.A.str.contains('<'),df.A.str.replace('<|>|/',''),np.nan)).ffill()
df
Out[1003]: 
               A    section
0        <fruit>      fruit
1          apple      fruit
2         orange      fruit
3           pear      fruit
4     watermelon      fruit
5       </fruit>      fruit
6    <furniture>  furniture
7          chair  furniture
8           sofa  furniture
9          table  furniture
10          desk  furniture
11  </furniture>  furniture

Если вы хотите быть более точным/конкретным/строгим, вы также можете проверить начало и конец строки, используя startswith и endswith.

df1['Section'] = pd.Series(np.where(df1.A.str.startswith('<') & df1.A.str.endswith('>'), df1.A.str.replace('<|>|/',''), np.nan)).ffill()
  • 0
    что вы подразумеваете под "IIUC"? Что это означает?
  • 1
    @LunchBox Если я правильно понимаю
Показать ещё 4 комментария
1

Я бы выбрал явное

import re

def parse_funky_xml(s):
  tag = None
  for x in s:
    if tag is None:
      match = re.match('<([^/]+)>', x)
      if match:
        tag = match.groups()[0]
      yield tag
    else:
      match = re.match(f'</{tag}>', x)
      yield tag
      if match:
        tag = None

df.assign(section=[*parse_funky_xml(df.A)])

               A    section
0        <fruit>      fruit
1          apple      fruit
2         orange      fruit
3           pear      fruit
4     watermelon      fruit
5       </fruit>      fruit
6    <furniture>  furniture
7          chair  furniture
8           sofa  furniture
9          table  furniture
10          desk  furniture
11  </furniture>  furniture

Ещё вопросы

Сообщество Overcoder
Наверх
Меню