Manejando NUMEROSOS números en números o pandas

Estoy haciendo una competencia en la que me proporcionan datos que son anónimos. Bastantes de las columnas tienen valores ENORMES. ¡El más grande tenía 40 dígitos! pd.read_csv pero esas columnas se convirtieron en objetos como resultado.

Mi plan original era reducir los datos, pero como se ven como objetos, no puedo hacer aritmética en estos.

¿Alguien tiene alguna sugerencia sobre cómo manejar grandes números en Pandas o Numpy?

Tenga en cuenta que he intentado convertir el valor a un uint64 sin suerte. Me sale el error “demasiado grande para convertir”

Puede usar los convertidores de Pandas para llamar a int o alguna otra función de conversión personalizada en la cadena a medida que se importan:

 import pandas as pd from StringIO import StringIO txt='''\ line,Big_Num,text 1,1234567890123456789012345678901234567890,"That sure is a big number" 2,9999999999999999999999999999999999999999,"That is an even BIGGER number" 3,1,"Tiny" 4,-9999999999999999999999999999999999999999,"Really negative" ''' df=pd.read_csv(StringIO(txt), converters={'Big_Num':int}) print df 

Huellas dactilares:

  line Big_Num text 0 1 1234567890123456789012345678901234567890 That sure is a big number 1 2 9999999999999999999999999999999999999999 That is an even BIGGER number 2 3 1 Tiny 3 4 -9999999999999999999999999999999999999999 Really negative 

Ahora prueba la aritmética:

 n=df["Big_Num"][1] print n,n+1 

Huellas dactilares:

 9999999999999999999999999999999999999999 10000000000000000000000000000000000000000 

Si tiene algún valor en la columna que pueda causar que se produzca un croar, puede hacer esto:

 txt='''\ line,Big_Num,text 1,1234567890123456789012345678901234567890,"That sure is a big number" 2,9999999999999999999999999999999999999999,"That is an even BIGGER number" 3,0.000000000000000001,"Tiny" 4,"a string","Use 0 for strings" ''' def conv(s): try: return int(s) except ValueError: try: return float(s) except ValueError: return 0 df=pd.read_csv(StringIO(txt), converters={'Big_Num':conv}) print df 

Huellas dactilares:

  line Big_Num text 0 1 1234567890123456789012345678901234567890 That sure is a big number 1 2 9999999999999999999999999999999999999999 That is an even BIGGER number 2 3 1e-18 Tiny 3 4 0 Use 0 for strings 

Luego, cada valor en la columna será un Python int o un float y soportará la aritmética.

Si tiene una columna de tipo mixto (algunos enteros, algunas cadenas) almacenada en una columna dtype = object, aún puede convertir a ints y realizar operaciones aritméticas. A partir de una columna de tipo mixto:

 >>> df = pd.DataFrame({"A": [11**44, "11"*22]}) >>> df A 0 6626407607736641103900260617069258125403649041 1 11111111111111111111111111111111111111111111 [2 rows x 1 columns] >>> df.dtypes, list(map(type, df.A)) (A object dtype: object, [, ]) 

Podemos convertir a ints:

 >>> df["A"] = df["A"].apply(int) >>> df.dtypes, list(map(type, df.A)) (A object dtype: object, [, ]) >>> df A 0 6626407607736641103900260617069258125403649041 1 11111111111111111111111111111111111111111111 [2 rows x 1 columns] 

Y luego realizar aritmética:

 >>> df // 11 A 0 602400691612421918536387328824478011400331731 1 1010101010101010101010101010101010101010101 [2 rows x 1 columns] 

Edición: Estos tampoco pueden ser representados (con precisión) como flotantes, simplemente no aumentan cuando lo intentas … probablemente es mejor usar el tipo de objeto y los largos como en la respuesta de DSM.

Pero puede hacerlo de forma incorrecta (utilizando el ejemplo de @ DSM):

 In [11]: df = pd.DataFrame({"A": [11**44, "11"*22]}).astype(float) In [12]: df Out[12]: A 0 6.626408e+45 1 1.111111e+43 [2 rows x 1 columns] In [13]: df.dtypes Out[13]: A float64 dtype: object 

Pero puede que no sea lo que quieres …

 In [21]: df.iloc[0, 0] Out[21]: 6.6264076077366411e+45 In [22]: long(df.iloc[0, 0]) Out[22]: 6626407607736641089115845702792172379125579776L In [23]: 11 ** 44 Out[23]: 6626407607736641103900260617069258125403649041L 

Como sugiere DSM, convierta a largo (y use el tipo de objeto) para no perder precisión:

 In [31]: df = pd.DataFrame({"A": [11**44, "11"*22]}).apply(long, 1) In [32]: df Out[32]: 0 6626407607736641103900260617069258125403649041 1 11111111111111111111111111111111111111111111 dtype: object