2017-10-20 33 views
6

J'ai un array comme ci-dessouscomportement np.isreal différent pandas.DataFrame et numpy.array

np.array(["hello","world",{"a":5,"b":6,"c":8},"usa","india",{"d":9,"e":10,"f":11}]) 

et un pandasDataFrame comme ci-dessous

df = pd.DataFrame({'A': ["hello","world",{"a":5,"b":6,"c":8},"usa","india",{"d":9,"e":10,"f":11}]}) 

Lorsque je demande à np.isrealDataFrame

df.applymap(np.isreal) 
Out[811]: 
     A 
0 False 
1 False 
2 True 
3 False 
4 False 
5 True 

Lorsque je fais np.isreal pour le tableau numpy.

np.isreal(np.array(["hello","world",{"a":5,"b":6,"c":8},"usa","india",{"d":9,"e":10,"f":11}])) 
Out[813]: array([ True, True, True, True, True, True], dtype=bool) 

Je dois à l'aide du np.isreal dans le mauvais cas d'utilisation, mais pouvez-vous me aide sur pourquoi le résultat est différent?

+0

Ceci est encore plus déroutant pour moi que la réponse que vous avez donnée pour déclencher cette question! :) Non seulement pourquoi est-ce différent, mais pourquoi différencie-t-on les chaînes et les dicts dans les «pandas»? – roganjosh

+1

@roganjosh J'ai juste le temps de le tester, même si nous l'utilisons dans le mauvais sens, nous attendons la même mauvaise réponse, mais celle-ci ..LOL – Wen

+1

Pandas est un peu un hareng rouge ici, qui utilise juste l'élément comportement pareil '[np.isreal (aa) pour aa dans np.array ([" bonjour "," monde ", {" a ": 5," b ": 6," c ": 8}," usa "," Inde ", {" d ": 9," e ": 10," f ": 11}])]' –

Répondre

6

Une réponse partielle est que isreal est uniquement destiné à être utilisé sur un tableau comme premier argument.

Vous voulez utiliser isrealobj sur chaque élément pour obtenir le bahavior que vous voyez ici:

In [11]: a = np.array(["hello","world",{"a":5,"b":6,"c":8},"usa","india",{"d":9,"e":10,"f":11}]) 

In [12]: a 
Out[12]: 
array(['hello', 'world', {'a': 5, 'b': 6, 'c': 8}, 'usa', 'india', 
     {'d': 9, 'e': 10, 'f': 11}], dtype=object) 

In [13]: [np.isrealobj(aa) for aa in a] 
Out[13]: [True, True, True, True, True, True] 

In [14]: np.isreal(a) 
Out[14]: array([ True, True, True, True, True, True], dtype=bool) 

qui ne laisse la question, qu'est-ce que np.isreal faire quelque chose qui n'est pas semblable à un tableau par exemple

In [21]: np.isrealobj("") 
Out[21]: True 

In [22]: np.isreal("") 
Out[22]: False 

In [23]: np.isrealobj({}) 
Out[23]: True 

In [24]: np.isreal({}) 
Out[24]: True 

Il se trouve cela découle de .imag depuis le test that isreal does est:

return imag(x) == 0 # note imag == np.imag 

et c'est tout.

In [31]: np.imag(a) 
Out[31]: array([0, 0, 0, 0, 0, 0], dtype=object) 

In [32]: np.imag("") 
Out[32]: 
array('', 
     dtype='<U1') 

In [33]: np.imag({}) 
Out[33]: array(0, dtype=object) 

Ceci recherche l'attribut .imag sur la baie.

In [34]: np.asanyarray("").imag 
Out[34]: 
array('', 
     dtype='<U1') 

In [35]: np.asanyarray({}).imag 
Out[35]: array(0, dtype=object) 

Je ne sais pas pourquoi ce n'est pas réglé dans le cas de la chaîne encore ...

+2

Cela ne répond pas complètement à la question de savoir ce que isreal fait ici, mais les docs indiquent clairement que le premier argument devrait ressembler à un tableau (donc je pense que tous les paris sont off ..) et nous devons regarder le code –

+0

Merci, Faites-moi savoir que toute la fonction 'numpy' ne peut pas être empruntée sans penser au calcul des pandas – Wen

+0

@Wen ça vient du comportement intéressant de' .imag' https : //github.com/numpy/numpy/blob/v1.13.0/numpy/lib/type_check.py#L221-L249 –

4

Je pense que c'est un petit bug dans Numpy pour être honnête. Ici, Pandas fait simplement une boucle sur chaque élément de la colonne et appelle np.isreal() dessus. .: par exemple

>>> np.isreal("a") 
False 
>>> np.isreal({}) 
True 

Je pense que le paradoxe est ici à voir avec la façon dont np.real() traite les entrées de dtype=object. Je suppose qu'il prend le pointeur d'objet et le traite comme un int, donc bien sûr np.isreal(<some object>) renvoie True. Sur un tableau de types mixtes comme np.array(["A", {}]), le tableau est de dtype=object donc np.isreal() traite tous les éléments (y compris les chaînes) comme il le ferait avec dtype=object.

Pour être clair, je pense que le bug est dans la façon dont np.isreal() traite les objets arbitraires dans un tableau dtype=object, mais je ne l'ai pas confirmé explicitement.

+2

nous étions tous les deux très rapides, vous venez de me battre :) –

+0

C'est une question étrange mais certainement intéressante? – Iguananaut

+1

Je suis une personne étrange ..LOL :-), il est normal pour moi – Wen

1

Il y a deux choses se passent ici.Le premier est souligné par les réponses précédentes en ce que np.isreal agit étrangement lorsqu'il est passé ojbects. Cependant, je pense que vous êtes également confus au sujet de ce que fait applymap. Difference between map, applymap and apply methods in Pandas est toujours une excellente référence.

Dans ce cas, ce que vous pensez que vous faites est en fait:

df.apply(np.isreal, axis=1) 

qui appelle essentiellement np.isreal (df), alors que df.applymap (np.isreal) est essentiellement appeler np.isreal sur chaque élément individuel de df. par exemple

np.isreal(df.A) 

array([ True, True, True, True, True, True], dtype=bool) 

np.array([np.isreal(x) for x in df.A]) 

array([False, False, True, False, False, True], dtype=bool) 
+0

Ah, bonne prise. – Iguananaut

+1

Relatif à ce commentaire: https://stackoverflow.com/questions/46856988/np-isreal-behavior-different-in-pandas-dataframe-and-numpy-array/46857114#comment80661655_46856988 –