Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在dtype=str的数据帧上使用dropna?_Python_Pandas_Dataframe_Nan_Missing Data - Fatal编程技术网

Python 如何在dtype=str的数据帧上使用dropna?

Python 如何在dtype=str的数据帧上使用dropna?,python,pandas,dataframe,nan,missing-data,Python,Pandas,Dataframe,Nan,Missing Data,当我有这样一个数据帧时: import pandas as pd import numpy as np df = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'), dtype=float) df.set_value('a', 'D', 4.0) df.set_value('b', 'E', 10.0) D E F a 4.0 NaN NaN b NaN 10.0 NaN c Na

当我有这样一个数据帧时:

import pandas as pd
import numpy as np    

df = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'), dtype=float)
df.set_value('a', 'D', 4.0)
df.set_value('b', 'E', 10.0)

     D     E   F
a  4.0   NaN NaN
b  NaN  10.0 NaN
c  NaN   NaN NaN
df2[~(df2 == 'n').all(axis=1)]
     D    E  F
a  foo    n  n
b    n  bar  n
通过调用以下命令,我可以轻松删除只包含
nan
的行:

df = df.dropna(how='all')
产生

     D     E   F
a  4.0   NaN NaN
b  NaN  10.0 NaN
除了在用
dtype=str
初始化的数据帧上,如何做同样的事情?以下操作不起作用:

df2 = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'), dtype='str')
df2.set_value('a', 'D', 'foo')
df2.set_value('b', 'E', 'bar')

     D    E  F
a  foo    n  n
b    n  bar  n
c    n    n  n
然后命令

df2 = df2.dropna(how='all')

返回未修改的数据帧。

首先调用
df.replace
,然后调用
df.dropna

In [1576]: df2.replace('n', np.nan).dropna(how='all')
Out[1576]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN
这似乎是最直接的选择。据我所见,一旦您使用
dtype=str
初始化数据帧,您就丢失了
NaN
s,因此这更像是一个最佳猜测替换(您可以拥有合法的非
NaN
条目,它们被标记为误报并被删除)


这里有一个类似于John Galt的解决方案,但保留了
NaN
s:

In [1584]: df2[~df2.eq('n')].dropna(how='all')
Out[1584]: 
     D    E    F
a  foo  NaN  NaN
b  NaN  bar  NaN

扩展Andrew L的评论,您不需要转换为
dtype=str
来设置值。您可以改用基于
.loc
的索引:

In [1586]: df2 = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'))
      ...: df2.loc['a', 'D'] = 'foo'
      ...: df2.loc['b', 'E'] = 'bar'
      ...: 

In [1587]: df2
Out[1587]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN
c  NaN  NaN NaN
现在

In [1588]: df2.dropna(how='all')
Out[1588]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN

首先调用
df.replace
,然后调用
df.dropna

In [1576]: df2.replace('n', np.nan).dropna(how='all')
Out[1576]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN
这似乎是最直接的选择。据我所见,一旦您使用
dtype=str
初始化数据帧,您就丢失了
NaN
s,因此这更像是一个最佳猜测替换(您可以拥有合法的非
NaN
条目,它们被标记为误报并被删除)


这里有一个类似于John Galt的解决方案,但保留了
NaN
s:

In [1584]: df2[~df2.eq('n')].dropna(how='all')
Out[1584]: 
     D    E    F
a  foo  NaN  NaN
b  NaN  bar  NaN

扩展Andrew L的评论,您不需要转换为
dtype=str
来设置值。您可以改用基于
.loc
的索引:

In [1586]: df2 = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'))
      ...: df2.loc['a', 'D'] = 'foo'
      ...: df2.loc['b', 'E'] = 'bar'
      ...: 

In [1587]: df2
Out[1587]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN
c  NaN  NaN NaN
现在

In [1588]: df2.dropna(how='all')
Out[1588]: 
     D    E   F
a  foo  NaN NaN
b  NaN  bar NaN

它们不再是
NaN
。你可以像这样过滤它们

In [503]: df2[~df2.eq('n').all(1)]
Out[503]:
     D    E  F
a  foo    n  n
b    n  bar  n

它们不再是
NaN
。你可以像这样过滤它们

In [503]: df2[~df2.eq('n').all(1)]
Out[503]:
     D    E  F
a  foo    n  n
b    n  bar  n

既然您已将
np.nan
转换为
n
,您还可以执行以下操作:

import pandas as pd
import numpy as np    

df = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'), dtype=float)
df.set_value('a', 'D', 4.0)
df.set_value('b', 'E', 10.0)

     D     E   F
a  4.0   NaN NaN
b  NaN  10.0 NaN
c  NaN   NaN NaN
df2[~(df2 == 'n').all(axis=1)]
     D    E  F
a  foo    n  n
b    n  bar  n

显然,如果您可能有包含“n”的真实数据,这是不安全的。

因为您已将
np.nan
转换为
n
,您还可以执行以下操作:

import pandas as pd
import numpy as np    

df = pd.DataFrame(np.nan, index=list('abc'), columns=list('DEF'), dtype=float)
df.set_value('a', 'D', 4.0)
df.set_value('b', 'E', 10.0)

     D     E   F
a  4.0   NaN NaN
b  NaN  10.0 NaN
c  NaN   NaN NaN
df2[~(df2 == 'n').all(axis=1)]
     D    E  F
a  foo    n  n
b    n  bar  n

显然,如果您的实际数据可能包含“n”,则这是不安全的。

您可以将字符串替换为real
numpy.nan
值:

df2.replace('n',np.nan).dropna(how = 'all')
这将起作用,但也将更改您可能希望保留的数据帧中的
'n'
值。在这种情况下,删除仅包含值
'n'
的行:

df2[(df2.T != 'n').any()]
此外,第二种解决方案的计算效率更高:

%timeit df2.replace('n',np.nan).dropna(how = 'all')
985 µs ± 8.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df2[(df2.T != 'n').any()]
449 µs ± 1.33 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

您可以用real
numpy.nan
值替换字符串:

df2.replace('n',np.nan).dropna(how = 'all')
这将起作用,但也将更改您可能希望保留的数据帧中的
'n'
值。在这种情况下,删除仅包含值
'n'
的行:

df2[(df2.T != 'n').any()]
此外,第二种解决方案的计算效率更高:

%timeit df2.replace('n',np.nan).dropna(how = 'all')
985 µs ± 8.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df2[(df2.T != 'n').any()]
449 µs ± 1.33 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)


它们不再是NaN,而是char
'n'
,所以你可以把它们过滤掉,但这里真正的问题是什么,
NaN
是一个数字事物,
str
不能表示它,所以从技术上讲它们不是
NaN
它们不再是
NaN
,而是字符
'n'
,所以你可以把它们过滤掉,但这里真正的问题是什么,
NaN
是一个数字的东西,
str
不能表示它,所以它们在技术上不是
NaN
Ok,这是一个令人不快的问题,但却是一个可靠的解决方案(上标)。当我没有指定
dtype
时,我不能将
set_值
与字符串一起使用,不幸的是…@Cleb为什么不使用
loc
设置值
df2.loc['a',D']='foo'
@AndrewL:With
loc
它确实有效,但与
set\u值
不起作用,后者应该更快。@Cleb是的,但是将
n
s转换为
NaN
s的惩罚将是你所遭受的。一定要重新考虑。我已经添加了一个MVCE来支持这个概念。谢谢,是的,我可能会选择
loc
;我只是想知道是否有更好的解决方案,谢谢你的详细回答。好的,这是一个令人不快的但却是一个坚实的工作(投票表决)。当我没有指定
dtype
时,我不能将
set_值
与字符串一起使用,不幸的是…@Cleb为什么不使用
loc
设置值
df2.loc['a',D']='foo'
@AndrewL:With
loc
它确实有效,但与
set\u值
不起作用,后者应该更快。@Cleb是的,但是将
n
s转换为
NaN
s的惩罚将是你所遭受的。一定要重新考虑。我已经添加了一个MVCE来支持这个概念。谢谢,是的,我可能会选择
loc
;我只是想知道是否有更好的解决方案,谢谢你的详细回答;这并不理想,因为实际数据可能等于
n
@Cleb,这恐怕是任何解决方案都要冒的风险;这不太理想,因为实际数据可能等于
n
@Cleb,我想这是一个你必须采取任何解决方案的机会。与另一个答案相同,但在时间比较上仍然投了较高的票。我最初投了你的反对票,因为这也是我的答案。现在我看到你添加了更多的内容,我删除了它,但你应该知道我知道是你报复否决了我的三个答案。这怎么可能是报复?我不知道是你投票否决了我。即使我做到了,我也不在乎。我对您的一些答案投了反对票,因为它们要么效率低下(例如使用lambda函数,基本上用于循环),要么有副作用(转换不需要的数据类型)。如果这伤害了你的感情,我很抱歉。嗯。。。如果是这样的话,你会有更多的答案被否决:)你应该在否决之前三思而后行,尤其是在愤怒/报复中否决。我不明白为什么这意味着