2017-02-15 23 views
6

Mam zagnieżdżoną listę ciągów, które chciałbym wyodrębnić im datę. Format daty to:pandas extractall() nie wyodrębnia wszystkich przypadków z wyrażeniem regularnym?

Two numbers (from 01 to 12) hyphen tree letters (a valid month) hyphen two numbers, for example: 08-Jan—07 or 03-Oct—01

Próbowałem użyć następującego wyrażenia regularnego:

r'\d{2}(—|-)(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{2,4}' 

Potem testowałem go w następujący sposób:

import pandas as pd 
df = pd.DataFrame({'blobs':['6-Feb- 1 4 Facebook’s virtual-reality division created a 3-EBÚ7 11 network of 500 free demo stations in Best Buy stores to give people a taste of VR using the Oculus Rift 90 GT 48 headset. But according to a Wednesday report from Business Insider, about 200 of the demo stations will close after low interest from consumers. 17-Feb-2014', 
         'I think in a store environment getting people to sit down and go through that experience of getting a headset on and getting set up is quite a difficult thing to achieve,” said Geoff Blaber, a CCS Insight analyst. 29—Oct-2012 Blaber 32 FAX 2978 expects that it will get easier when companies can convince 18-Oct-12 credit cards. ' 
          ]}) 
df 

Następnie:

df['blobs'].str.extractall(r'\d{2}(—|-)(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{2,4}') 

Niemniej jednak nie działają. Poprzedniego regex nie daje mi niczego (czyli po prostu hypens -):

Col 
0 NaN 
1 - 
2 - 
3 NaN 
4 NaN 
5 - 
... 
n - 

Jak mogę je naprawić, aby dostać ?:

  Col 
0 6-Feb-14, 17-Feb-2014 
1 29—Oct-2012, 18-Oct-12 

UPDATE

Próbowałem również:

import re 
df['col'] = df.blobs.apply(lambda x: re.findall('\d{2}(—|-)(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{2,4}',x)) 
s = df.apply(lambda x: pd.Series(x['col']),axis=1).stack().reset_index(level=1, drop=True) 
s.name = "col" 
df = df.drop('col') 
df 

Jednak mam również:

ValueError        Traceback (most recent call last) 
<ipython-input-4-5e9a34bd159f> in <module>() 
     3 s = df.apply(lambda x: pd.Series(x['col']),axis=1).stack().reset_index(level=1, drop=True) 
     4 s.name = "col" 
----> 5 df = df.drop('col') 
     6 df 

/usr/local/lib/python3.5/site-packages/pandas/core/generic.py in drop(self, labels, axis, level, inplace, errors) 
    1905     new_axis = axis.drop(labels, level=level, errors=errors) 
    1906    else: 
-> 1907     new_axis = axis.drop(labels, errors=errors) 
    1908    dropped = self.reindex(**{axis_name: new_axis}) 
    1909    try: 

/usr/local/lib/python3.5/site-packages/pandas/indexes/base.py in drop(self, labels, errors) 
    3260    if errors != 'ignore': 
    3261     raise ValueError('labels %s not contained in axis' % 
-> 3262         labels[mask]) 
    3263    indexer = indexer[~mask] 
    3264   return self.delete(indexer) 

ValueError: labels ['col'] not contained in axis 
+1

':' to literówka, prawda (?)? Spróbuj "r" \ b \ d {2} - (?: Jan | Feb | Mar | Apr | Maj | Jun | Jul | Aug | Sep | Oct | Nov | Dec) - \ d {2} \ b "'. Jeśli mogą istnieć znaki kreski en lub em, zamień '-' na' [---] '. –

+2

W skrócie, twoje wyrażenia regularne nie pasują do myślników. – Kevin

+1

Jeśli chcesz, aby '6-lut' był akceptowany, musisz zezwolić na _na_ numer z góry, a nie dwa. na przykład '\ d {1,2}' – khelwood

Odpowiedz

1

Podczas korzystania Series.str.extract lub Series.str.extractall, że złapanych podciągi są zwracane, a nie całych fraz. Musisz więc upewnić się, że przechwycisz (tzn. Dodajesz ( i )) do części wzoru, który musisz pobrać.

Teraz, kilka oczekiwanych mecze w swoich wierszach uczynić go bardziej trudne do zrobienia z extractall, wydaje się, można użyć Series.str.findall że może wrócić cały mecze jeśli żadna grupa przechwytywania jest określona we wzorcu.

Zastosowanie

rx = r'\b\d{1,2}[-–—](?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[-–—](?:\d{4}|\d{2})\b' 
df['Col'] = df['blobs'].str.findall(rx).apply(','.join) 

.apply(','.join) przekształci wykazów łańcuchów oddzielony przecinkami w Col kolumny.

Wzór oznacza:

  • \b - słowo brzegowe
  • \d{1,2} - 1 lub 2 cyfry
  • [-–—] - łącznik, EM lub en-myślnik
  • (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) - któregokolwiek z 12-miesięczne skrócone nazwy:
  • [-–—] - łącznik, em- lub en-dash
  • (?:\d{4}|\d{2}) - 4 lub 2 cyfry
  • \b - granica słowo
+0

Dzięki, jeszcze jedno szybkie pytanie ... w przypadku dopasowania górnej i dolnej jest w porządku dodać '(? I)' ?. na przykład: r '\ b \ d {1,2} [---] ((?)): Jan | Feb | Mar | Apr | Maj | Jun | Jul | Aug | Sep | Oct | Nov | Dec) [---] (?: \ D {4} | \ d {2}) \ b ' –

+1

W Pythonie * 're' *, miejsce wbudowanego' (? I) 'modyfikatora nie robi żadnej różnicy. Jeśli umieścisz go na końcu, sprawi to, że * cały * wzorzec będzie niewrażliwy. Użyj 'rx = r '(? I) \ b \ d {1,2} [---] (?: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec) [---] (?: \ D {4} | \ d {2}) \ b''pl –

+1

Dziękuję, że twoja odpowiedź naprawdę pomogła mi wyjaśnić problem z ekstraktem –