Soru FutureWarning: elementwise karşılaştırma başarısız oldu; skaler döndürme, ancak gelecekte elementer karşılaştırma yapacak


Panda'ları kullanıyorum 0.19.1 Python 3. üzerinde Bu kod satırlarında bir uyarı alıyorum. Dize tüm satır numaralarını içeren bir liste almaya çalışıyorum Peter sütunta mevcut Unnamed: 5.

df = pd.read_excel(xls_path)
myRows = df[df['Unnamed: 5'] == 'Peter'].index.tolist()

Uyarı:

"\Python36\lib\site-packages\pandas\core\ops.py:792: FutureWarning: elementwise 
comparison failed; returning scalar, but in the future will perform 
elementwise comparison 
result = getattr(x, name)(y)"

Bu FutureWarning nedir ve işe yaradığı için onu görmezden gelmeliyim.


18
2017-11-17 15:46


Menşei


Örnek veriler vermelisiniz. - IanS


Cevaplar:


Bu FutureWarning, Pandalardan değil, numpy'den ve hata da matplotlib ve diğerlerini etkiliyor, işte sorunun kaynağına daha yakın olan uyarıyı yeniden üretme:

import numpy as np
print(np.__version__)   # Numpy version '1.12.0'
'x' in np.arange(5)       #Future warning thrown here

FutureWarning: elementwise comparison failed; returning scalar instead, but in the 
future will perform elementwise comparison
False

Bu hatayı çift eşitlik operatörünü kullanarak yeniden üretmenin bir başka yolu:

import numpy as np
np.arange(5) == np.arange(5).astype(str)    #FutureWarning thrown here

Matplotlib'in bu FutureWarning tarafından titiz çizim uygulaması altında etkilenen bir örneği: https://matplotlib.org/examples/pylab_examples/quiver_demo.html

Burada neler oluyor?

Numpy ile sayısal python arasında, bir dizeyi numpy'nin sayısal türleriyle karşılaştırdığınızda ne olacağı konusunda bir anlaşmazlık vardır. Sol işlenenin python'un çimeni, ilkel bir dizilim olduğuna dikkat edin ve ortadaki işlem python'un çim kısmıdır, ancak sağ işlenen, numpy'nin çimidir. Bir Python stili Scalar veya boolean bir Numpy stili ndarray dönün mü? Numpy bool ndarrayını söylüyor, Pythonic geliştiricileri de aynı fikirde değil. Klasik duruş.

Eğer dizide öğe varsa elemansal karşılaştırma mı yoksa Skaler mi olmalı?

Kodunuz veya kitaplığınız kullanıyorsa in veya == python dizesini numpy ndarrays ile karşılaştırmak için operatörler, uyumlu değildir, bu yüzden eğer denerseniz, bir skaler döndürür, ancak şimdilik sadece. Uyarı, gelecekte bu davranışın değişebileceğini, böylece python / numpy Numpy stilini benimsemeye karar verdiyse, kodunuzun tüm halıda kusacağını gösterir.

Gönderilen Hata raporları:

Numpy ve Python bir çarpıklık içerisindedir, şimdilik işlem bir skaler döndürür, ancak gelecekte değişebilir.

https://github.com/numpy/numpy/issues/6784

https://github.com/pandas-dev/pandas/issues/7830

İki geçici çözüm:

Ya python ve numpy versiyonunuzu kilitleyin ve uyarıları dikkate almayın ya da sol ve sağ işlenenlerinizi ortak bir çim alanından elde edin.

Uyarıyı genel olarak bastır:

import warnings
import numpy as np
warnings.simplefilter(action='ignore', category=FutureWarning)
print('x' in np.arange(5))   #returns False, without Warning

Uyarının hat bazında bastırılması.

import warnings
import numpy as np

with warnings.catch_warnings():
    warnings.simplefilter(action='ignore', category=FutureWarning)
    print('x' in np.arange(2))   #returns False, warning is suppressed

print('x' in np.arange(10))   #returns False, Throws FutureWarning

Sadece ismiyle uyarıyı bastırın, daha sonra python ve numpy'nin mevcut versiyonunu anlatan, bu kodun kırılgan olduğunu söyleyen ve bu sürümleri gerektiren ve buraya bir bağlantı koyduğunu söyleyen yüksek sesli bir yorum yapın. Tenekeyi yolda bırak.


24
2017-10-13 01:07



Ugh. Eğer biraz miktarım varsa thing (numpy türü olabilir ya da olmayabilir; bilmiyorum) ve görmek isterim thing == 'some string' ve basit olsun bool sonuç ne yapmalıyım? np.atleast_1d(thing)[0] == 'some string'? Ama bu bir joker koymak için güçlü değil 'some string' bir dizinin ilk elemanında. Sanırım türünü test etmek zorundayım. thing önce ve sonra sadece == Bir dizge olup olmadığını sınayın (veya numpy nesnesi değil). - EL_DON
Bundan emin olmak için, her satırda kendi C stili veya Java stili kontrol sarma kodunuzu kullanmanız gerekir. == ve in Python'un çöken ideolojisi veya numpy'nin vectorized ideolojisi ile beklediğiniz gibi çalışacak. Python Geliştiricileri bu konuda uyarıldı, ama sen dinlemedin, şimdi bedeli çift eşittir ve in yanlışlıkla bir özel geçirdiğinizde tanımlanmamış davranış gerçekleştirme numpy.googah.blimflarg bekliyor bir pandalar fonksiyonuna yazın pandas.vehicle.subspaceresponder yazın. Java / C gibi hassas bir tip hatası vermektense, sadece halının her yerine yayılıyor. - Eric Leschinski
Şimdiye kadar, uzaklaşacağım gibi görünüyor str(thing) == 'some string' Bu özel durum için. Karşılaştırmak için daha büyük bir veri kümesine sahip olsaydım büyük bir zaman kaybı olabilirmiş gibi görünüyor. - EL_DON
Bu stackoverflow postu, Python'un "kovboy koli bandı programlaması ideolojisinin bir örneğidir: Kod hızlı, regresyon testini yapma, hata yapma, bir şeyleri kırma, öğrenme, sonra düzeltme, sonra tekrar et". C ++ ve Java gibi diğer daha hızlı ve daha duyarlı dillerde, bu sorun asla bir sorun olmayacaktı çünkü türler bir milyar formdan herhangi birine girmekten ve atmosferin içinde süzülmekten ziyade, derlenmişler ve derleme süresinde guarenteed. tam kaosun Dua, sözleşmeyi daha fazla değiştirmem. youtube.com/watch?v=WpE_xMRiCLE - Eric Leschinski
Aslında, bir numpy.ndarray öğesini boş bir listeyle karşılaştırmaya çalıştığınızda, bu gelecekteki uyarı da yükseltilir. Örneğin, yürütme np.array([1, 2]) == [] uyarıyı da artıracaktır. - 1313e


Aynı uyarı mesajındaki deneyimim TypeError'dan kaynaklandı.

TypeError: geçersiz tür karşılaştırması

Yani, veri tipini kontrol etmek isteyebilirsiniz. Unnamed: 5

for x in df['Unnamed: 5']:
  print(type(x))  # are they 'str' ?

Uyarı mesajını şöyle kopyalayabilirim:

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3, 2), columns=['num1', 'num2'])
df['num3'] = 3
df.loc[df['num3'] == '3', 'num3'] = 4  # TypeError and the Warning
df.loc[df['num3'] == 3, 'num3'] = 4  # No Error

Umarım yardımcı olur.


1
2017-11-27 17:58



Kodunuzu, uyarıyı göstermek için çok fazla gereksiz hareketli parça vardır. Pandalar bu ekstra TypeError ile sizi gösterir ama bu Pandalar gelen hasar kontrolü, Kaynak uyarı Numpy ve Python arasında bir anlaşmazlık olduğunu ve değerlendirmesinde ortaya çıkan df['num3'] == '3'. - Eric Leschinski


Dizileriniz çok büyük değilse veya çok fazla şeyiniz yoksa, sol tarafa doğru zorlamaktan kurtulabilirsiniz. == dize olmak:

myRows = df[str(df['Unnamed: 5']) == 'Peter'].index.tolist()

Ama bu ~ 1.5 kat daha yavaşsa df['Unnamed: 5']bir dize, 25-30 kat daha yavaşsa df['Unnamed: 5'] küçük bir numpy dizisidir (uzunluk = 10) ve 100 (100 den fazla deneme) ortalaması olan bir numpy dizisi ise 150-160 kat daha yavaştır.

a = linspace(0, 5, 10)
b = linspace(0, 50, 100)
n = 500
string1 = 'Peter'
string2 = 'blargh'
times_a = zeros(n)
times_str_a = zeros(n)
times_s = zeros(n)
times_str_s = zeros(n)
times_b = zeros(n)
times_str_b = zeros(n)
for i in range(n):
    t0 = time.time()
    tmp1 = a == string1
    t1 = time.time()
    tmp2 = str(a) == string1
    t2 = time.time()
    tmp3 = string2 == string1
    t3 = time.time()
    tmp4 = str(string2) == string1
    t4 = time.time()
    tmp5 = b == string1
    t5 = time.time()
    tmp6 = str(b) == string1
    t6 = time.time()
    times_a[i] = t1 - t0
    times_str_a[i] = t2 - t1
    times_s[i] = t3 - t2
    times_str_s[i] = t4 - t3
    times_b[i] = t5 - t4
    times_str_b[i] = t6 - t5
print('Small array:')
print('Time to compare without str conversion: {} s. With str conversion: {} s'.format(mean(times_a), mean(times_str_a)))
print('Ratio of time with/without string conversion: {}'.format(mean(times_str_a)/mean(times_a)))

print('\nBig array')
print('Time to compare without str conversion: {} s. With str conversion: {} s'.format(mean(times_b), mean(times_str_b)))
print(mean(times_str_b)/mean(times_b))

print('\nString')
print('Time to compare without str conversion: {} s. With str conversion: {} s'.format(mean(times_s), mean(times_str_s)))
print('Ratio of time with/without string conversion: {}'.format(mean(times_str_s)/mean(times_s)))

Sonuç:

Small array:
Time to compare without str conversion: 6.58464431763e-06 s. With str conversion: 0.000173756599426 s
Ratio of time with/without string conversion: 26.3881526541

Big array
Time to compare without str conversion: 5.44309616089e-06 s. With str conversion: 0.000870866775513 s
159.99474375821288

String
Time to compare without str conversion: 5.89370727539e-07 s. With str conversion: 8.30173492432e-07 s
Ratio of time with/without string conversion: 1.40857605178

0
2018-04-13 16:54





Bunun için hızlı bir çözüm kullanmaktır. numpy.core.defchararray. Aynı uyarı mesajıyla da karşılaştım ve yukarıdaki modülü kullanarak çözebiliyordum.

import numpy.core.defchararray as npd
resultdataset = npd.equal(dataset1, dataset2)

0
2018-06-23 04:20





Ben ayarlamaya çalıştığımda aynı hatayı alıyorum index_col bir dosyaya okuma Pandaveri çerçevesi

df = pd.read_csv('my_file.tsv', sep='\t', header=0, index_col=['0'])  ## or same with the following
df = pd.read_csv('my_file.tsv', sep='\t', header=0, index_col=[0])

Daha önce hiç böyle bir hatayla karşılaşmadım. Hala bunun arkasındaki sebebi anlamaya çalışıyorum (@Eric Leschinski açıklamasını ve diğerlerini kullanarak).

Her neyse, aşağıdaki yaklaşım şu an için sorunu çözer:

df = pd.read_csv('my_file.tsv', sep='\t', header=0)  ## not setting the index_col
df.set_index(['0'], inplace=True)

Bu tür davranışların sebebini anladığım anda bunu güncelleyeceğim.


0
2017-08-20 15:09