पांडा में डेटाफ्रेम से अनंत मूल्यों को छोड़ना?


219

रीसेट के बिना एक पांडा डेटा फ़्रेम से नैन और inf / -inf मानों को छोड़ने का सबसे तेज़ / सरल तरीका क्या है mode.use_inf_as_null? मैं उपयोग करने में सक्षम होना चाहते हैं subsetऔर howके तर्कों dropna, साथ सिवाय infमाना मान अनुपलब्ध है, जैसे:

df.dropna(subset=["col1", "col2"], how="all", with_inf=True)

क्या यह संभव है? क्या लापता मूल्यों की अपनी परिभाषा में dropnaशामिल करने के लिए बताने का कोई तरीका है inf?

जवाबों:


416

सबसे आसान तरीका पहले replaceNaN के लिए होगा:

df.replace([np.inf, -np.inf], np.nan)

और फिर उपयोग करें dropna:

df.replace([np.inf, -np.inf], np.nan).dropna(subset=["col1", "col2"], how="all")

उदाहरण के लिए:

In [11]: df = pd.DataFrame([1, 2, np.inf, -np.inf])

In [12]: df.replace([np.inf, -np.inf], np.nan)
Out[12]:
    0
0   1
1   2
2 NaN
3 NaN

एक ही विधि एक श्रृंखला के लिए काम करेगी।


2
infकिसी पूर्वनिर्धारित intजैसे कि 0एक निश्चित कॉलम में मूल्यों को "विनिमय" कैसे किया जा सकता है ?
3kstc

4
@ 3kstc उपयोग .replace(..., 0)। स्तंभों पर बस करने के लिए आप उन स्तंभों को अपडेट करते हैंdf[cols] = df[cols].replace(..., 0)
एंडी हेडन

3
शायद यह निर्दिष्ट करने के लायक है कि replaceजगह में काम नहीं करता है, इसलिए एक नया DataFrameलौटा है
मार्को

36

विकल्प के संदर्भ में, यह स्थायी रूप से सेटिंग के बिना संभव है use_inf_as_na। उदाहरण के लिए:

with pd.option_context('mode.use_inf_as_na', True):
    df = df.dropna(subset=['col1', 'col2'], how='all')

बेशक इसे स्थायी infरूप से इलाज के लिए सेट किया जा सकता हैNaN

pd.set_option('use_inf_as_na', True)

पुराने संस्करणों के लिए, के use_inf_as_naसाथ बदलें use_inf_as_null


6
यह सबसे पठनीय उत्तर है और फलस्वरूप सबसे अच्छा है, भले ही यह मूल प्रश्न में अक्षर (लेकिन आत्मा में नहीं) का उल्लंघन करता है।
जोजफ

2
(कम से कम) 0.24 के रूप में पंडों को use_inf_as_nullहटा दिया गया था और भविष्य के संस्करण में हटा दिया जाएगा। use_inf_as_naइसके बजाय उपयोग करें । उत्तर जोड़ें / अपडेट करें?
होकॉन टी।

1
infपरिचालन स्तर के बजाय वैश्विक सेटिंग स्तरों पर शून्य के रूप में व्यवहार करने के लिए यह एक बेहतर विकल्प है। यह संभावित रूप से पहले मानों को लागू करने में समय बचाता है।
ताओपुर

15

यहाँ .locएक श्रृंखला पर नैन के साथ inf को बदलने के लिए एक और तरीका है :

s.loc[(~np.isfinite(s)) & s.notnull()] = np.nan

तो, मूल प्रश्न के जवाब में:

df = pd.DataFrame(np.ones((3, 3)), columns=list('ABC'))

for i in range(3): 
    df.iat[i, i] = np.inf

df
          A         B         C
0       inf  1.000000  1.000000
1  1.000000       inf  1.000000
2  1.000000  1.000000       inf

df.sum()
A    inf
B    inf
C    inf
dtype: float64

df.apply(lambda s: s[np.isfinite(s)].dropna()).sum()
A    2
B    2
C    2
dtype: float64

11

उपयोग (तेज और सरल):

df = df[np.isfinite(df).all(1)]

यह उत्तर एक अन्य प्रश्न में डगआर के उत्तर पर आधारित है । यहाँ एक उदाहरण कोड:

import pandas as pd
import numpy as np
df=pd.DataFrame([1,2,3,np.nan,4,np.inf,5,-np.inf,6])
print('Input:\n',df,sep='')
df = df[np.isfinite(df).all(1)]
print('\nDropped:\n',df,sep='')

परिणाम:

Input:
    0
0  1.0000
1  2.0000
2  3.0000
3     NaN
4  4.0000
5     inf
6  5.0000
7    -inf
8  6.0000

Dropped:
     0
0  1.0
1  2.0
2  3.0
4  4.0
6  5.0
8  6.0

7

फिर भी एक और उपाय isinविधि का उपयोग करना होगा । यह निर्धारित करने के लिए इसका उपयोग करें कि क्या प्रत्येक मान अनंत या अनुपलब्ध है और फिर allयह निर्धारित करने के लिए विधि को निर्धारित करें कि क्या पंक्तियों में सभी मान अनंत या अनुपलब्ध हैं।

अंत में, उस परिणाम की उपेक्षा का उपयोग उन पंक्तियों का चयन करने के लिए करें जिनमें बूलियन इंडेक्सिंग के माध्यम से सभी अनंत या लापता मूल्य नहीं हैं।

all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]

7

उपरोक्त समाधान infउन लक्ष्यों को संशोधित करेगा जो लक्ष्य कॉलम में नहीं हैं। यह उपाय करने के लिए,

lst = [np.inf, -np.inf]
to_replace = {v: lst for v in ['col1', 'col2']}
df.replace(to_replace, np.nan)

3
अजगर 2.7 और उच्च समर्थन {v: lst for v in cols}
तानाशाहों का

4

आप के pd.DataFrame.maskसाथ उपयोग कर सकते हैं np.isinf। आपको पहले यह सुनिश्चित करना चाहिए कि आपकी डेटाफ़्रेम श्रृंखला सभी प्रकार की हो float। फिर dropnaअपने मौजूदा तर्क के साथ उपयोग करें।

print(df)

       col1      col2
0 -0.441406       inf
1 -0.321105      -inf
2 -0.412857  2.223047
3 -0.356610  2.513048

df = df.mask(np.isinf(df))

print(df)

       col1      col2
0 -0.441406       NaN
1 -0.321105       NaN
2 -0.412857  2.223047
3 -0.356610  2.513048
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.