Панды Использование оператора If для перехода строка за строкой - PullRequest
0 голосов
/ 27 августа 2018

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

Допустим, у меня есть кадр данных, который выглядит следующим образом:

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>

Мне нужен фрейм данных, который выглядит следующим образом:

             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 для перехода строка за строкой, но у меня возникли проблемы с булевой логикой, когда я это сделал.

Edit # 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>

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Я бы выбрал быть явным

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
0 голосов
/ 27 августа 2018

IIUC с помощью contains найдите строку и np.where присвойте значение, затем с помощью ffill заполните 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...