Metinlerden sayısal veri çıkarma, özellikle veri temizleme ve web scraping’te Python programlamasında yaygın bir görevdir. Bu makale, farklı senaryolara ve karmaşıklık seviyelerine hitap eden, bunu başarmak için çeşitli etkili ve çok yönlü yöntemleri ele almaktadır.
İçerik Tablosu
- Yöntem 1: Regüler İfadelerden Faydalanma
- Yöntem 2: Liste Kavrama Kullanımı
- Yöntem 3:
filter
veisdigit()
Birleştirme - Yöntem 4: Karmaşık Desenler için Gelişmiş Regüler İfadeler
- Sayı Formatlarındaki Değişimlerin Ele Alınması
- Sonuç
Yöntem 1: Regüler İfadelerden Faydalanma
Regüler ifadeler (regex), özellikle karmaşık metin yapıları için güçlü ve esnek bir yaklaşım sunar. Python’ın re
modülü bu işlemi kolaylaştırır.
import re
def extract_numbers_regex(text):
"""Regüler ifadeler kullanarak bir metinden sayıları çıkarır."""
numbers = re.findall(r'-?d+(.d+)?', text) # Tam sayıları ve ondalık sayıları, negatif sayılar dahil olmak üzere eşleştirir
return [float(num) for num in numbers]
text = " -12 elma ve 3.14 portakal, ayrıca 12345 var."
numbers = extract_numbers_regex(text)
print(numbers) # Çıktı: [-12.0, 3.14, 12345.0]
Bu geliştirilmiş regex r'-?d+(.d+)?'
negatif sayıları ve ondalıkları etkili bir şekilde işler.
Yöntem 2: Liste Kavrama Kullanımı
Liste kavrama, sayıların açıkça belirtildiği daha basit senaryolar için ideal, özlü ve Pythonik bir çözüm sağlar.
def extract_numbers_list_comprehension(text):
"""Liste kavrama kullanarak bir metinden tam sayıları çıkarır."""
return [int(c) for c in text if c.isdigit()]
text = "123abc456"
numbers = extract_numbers_list_comprehension(text)
print(numbers) # Çıktı: [1, 2, 3, 4, 5, 6]
Bu yöntem, tek tek rakamları çıkarmak için etkilidir, ancak çok basamaklı sayılar veya ondalık noktalı sayılar için uygun olmayabilir.
Yöntem 3: filter
ve isdigit()
Birleştirme
Bu fonksiyonel yaklaşım, daha basit durumlar için uygun, açık ve okunabilir bir çözüm için filter()
ve isdigit()
kullanır.
def extract_numbers_filter(text):
"""filter ve isdigit() kullanarak bir metinden tam sayıları çıkarır."""
numbers = list(filter(str.isdigit, text))
return [int(num) for num in numbers]
text = "1a2b3c4d5"
numbers = extract_numbers_filter(text)
print(numbers) #Çıktı: [1, 2, 3, 4, 5]
Liste kavramaya benzer şekilde, bu yöntem tek tek rakamları çıkarır ve daha karmaşık sayı formatlarını işlemez.
Yöntem 4: Karmaşık Desenler için Gelişmiş Regüler İfadeler
Bilimsel gösterimdeki veya binlik ayraçlı sayılar gibi karmaşık desenleri işlerken regüler ifadeler gerçekten öne çıkar.
import re
def extract_numbers_complex(text):
"""Regüler ifade kullanarak bir metinden (bilimsel gösterim dahil) sayıları çıkarır."""
numbers = re.findall(r'-?d+(?:,d{3})*(?:.d+)?(?:[eE][+-]?d+)?', text)
return [float(num.replace(',', '')) for num in numbers]
text = "Fiyat $1,234.56 ve miktar 1.23e-5. Başka bir fiyat 100,000"
numbers = extract_numbers_complex(text)
print(numbers) # Çıktı: ['1234.56', '1.23e-5', '100000']
Bu regex, binlik ayraç olarak virgülleri ve bilimsel gösterimi işler. replace(',', '')
virgülleri ondalık sayıya dönüştürmeden önce kaldırır.
Sayı Formatlarındaki Değişimlerin Ele Alınması
Çeşitli formatlara uyum sağlamak için şu noktaları göz önünde bulundurun:
- Negatif sayılar: Regex deseninizin başına
-?
ekleyin (örneğin,r'-?d+'
). - Bilimsel gösterim: Üsleri işlemek için
(?:[eE][+-]?d+)?
ekleyin (Yöntem 4’te gösterildiği gibi). - Binlik ayraçları: İsteğe bağlı binlik ayraçları eşleştirmek için
(?:,d{3})*
kullanın (Yöntem 4’te gösterildiği gibi). - Para birimi sembolleri: Çıkarmadan önce para birimi sembollerini kaldırmak için metinizi ön işleyin veya daha karmaşık bir regex kullanın.
Sonuç
En uygun yöntem, girdi metinlerinizin karmaşıklığna ve istenen hassasiyete bağlıdır. Basit durumlar için liste kavrama veya filter
yeterli olabilir. Bununla birlikte, sağlamlık ve çeşitli sayı formatlarını işlemek için regüler ifadeler çok değerlidir.