【问题标题】:Why does boolean indexing return all NaNs为什么布尔索引返回所有 NaN
【发布时间】:2016-07-10 11:28:56
【问题描述】:

我有这个 CSV 文件 emp.csv:

index   empno   ename   job mgr hiredate    sal comm    deptno
0,  7839,   KING,   PRESIDENT,  0,  1981-11-17,     5000,   0,  10
1,  7698,   BLAKE,  MANAGER,    7839,   1981-05-01, 2850,   0,  30
2,  7782,   CLARK,  MANAGER,    7839,   1981-05-09, 2450,   0,  10
3,  7566,   JONES,  MANAGER,    7839,   1981-04-01, 2975,   0,  20
4,  7654,   MARTIN, SALESMAN,   7698,   1981-09-10, 1250,   1400,   30
5,  7499,   ALLEN,  SALESMAN,   7698,   1981-02-11, 1600    300,    30
6,  7844,   TURNER, SALESMAN,   7698,   1981-08-21, 1500,   0,  30
7,  7900,   JAMES,  CLERK,      7698,   1981-12-11, 950,    0,  30
8,  7521,   WARD,   SALESMAN,   7698,   1981-02-23, 1250,   500,    30
9,  7902,   FORD,   ANALYST,    7566,   1981-12-11, 3000,   0,  20
10, 7369,   SMITH,  CLERK,      7902,   1980-12-09, 800,    0,  20
11, 7788,   SCOTT,  ANALYST,    7566    1982-12-22, 3000,   0,  20
12, 7876,   ADAMS,  CLERK,      7788,   1983-01-15, 1100,   0,  20
13, 7934,   MILLER, CLERK,      7782,   1982-01-11, 1300,   0,  10

使用下面的代码,我得到了所有NaN的:

import csv
import sys
import pandas as pd
import dateutil

# Load data from csv file
emp = pd.DataFrame.from_csv("D:\R data\emp.csv")
# Convert date from string to date times`enter code here`
emp['hiredate'] = emp['hiredate'].apply(dateutil.parser.parse, dayfirst=True)
jonessal = emp[['sal']][emp['ename']=='JONES']
empename = emp[['ename','sal']][emp['sal'] > jonessal] 
print(empename)

这是代码的输出:

index           
0       NaN  NaN
1       NaN  NaN
2       NaN  NaN
3       NaN  NaN
4       NaN  NaN
5       NaN  NaN
6       NaN  NaN
7       NaN  NaN
8       NaN  NaN
9       NaN  NaN
10      NaN  NaN
11      NaN  NaN
12      NaN  NaN
13      NaN  NaN

我想要的输出是:

index             
0       KING  5000
9       FORD  3000
11     SCOTT  3000

我以为变量jonesal的值是2975,结果是NaN

如果我用empename = emp[['ename','sal']][emp['sal'] > 2975 ] 硬编码薪水,它可以正常工作,但是当我使用变量时,它会返回所有NaN:empename = emp[['ename','sal']][emp['sal'] > jonessal]

【问题讨论】:

  • Yu,选择代码后使用“{}”形按钮获取正确格式

标签: python python-3.x csv pandas


【解决方案1】:

jonessal 是一个数据帧。

emp[['ename','sal']][emp['sal'] > jonessal] 

在这里,emp['sal'] > jonessal 的比较不是针对标量,并且由于广播它返回一个奇怪的 DataFrame。由于索引/形状不匹配,您的最终结果由 NaN 组成。

在这里,您假设只有一名员工叫 Jones。按照相同的假设,您可以得到标量:

jonessal = emp.loc[emp['ename']=='JONES', 'sal'].values[0]

.values 返回一个数组,[0] 来自单一员工假设。)

现在,它会返回相同的结果:

emp[['ename','sal']][emp['sal'] > jonessal]
Out[81]: 
    ename   sal
0    KING  5000
9    FORD  3000
11  SCOTT  3000

【讨论】:

    【解决方案2】:

    我认为你需要 read_csvboolean indexingix,它们只过滤列 enamesal

    import pandas as pd
    import io
    
    temp=u"""index   empno   ename   job mgr hiredate    sal comm    deptno
    0,  7839,   KING,   PRESIDENT,  0,  1981-11-17,     5000,   0,  10
    1,  7698,   BLAKE,  MANAGER,    7839,   1981-05-01, 2850,   0,  30
    2,  7782,   CLARK,  MANAGER,    7839,   1981-05-09, 2450,   0,  10
    3,  7566,   JONES,  MANAGER,    7839,   1981-04-01, 2975,   0,  20
    4,  7654,   MARTIN, SALESMAN,   7698,   1981-09-10, 1250,   1400,   30
    5,  7499,   ALLEN,  SALESMAN,   7698,   1981-02-11, 1600,    300,    30
    6,  7844,   TURNER, SALESMAN,   7698,   1981-08-21, 1500,   0,  30
    7,  7900,   JAMES,  CLERK,      7698,   1981-12-11, 950,    0,  30
    8,  7521,   WARD,   SALESMAN,   7698,   1981-02-23, 1250,   500,    30
    9,  7902,   FORD,   ANALYST,    7566,   1981-12-11, 3000,   0,  20
    10, 7369,   SMITH,  CLERK,      7902,   1980-12-09, 800,    0,  20
    11, 7788,   SCOTT,  ANALYST,    7566,    1982-12-22, 3000,   0,  20
    12, 7876,   ADAMS,  CLERK,      7788,   1983-01-15, 1100,   0,  20
    13, 7934,   MILLER, CLERK,      7782,   1982-01-11, 1300,   0,  10"""
    #after testing replace io.StringIO(temp) to filename
    emp = pd.read_csv(io.StringIO(temp), 
                     skipinitialspace=True,
                     skiprows=1, 
                     parse_dates=[5], 
                     names=['index','empno','ename', 'job','mgr','hiredate','sal','comm','deptno'])
    
    print (emp)
        index  empno   ename        job   mgr   hiredate   sal  comm  deptno
    0       0   7839    KING  PRESIDENT     0 1981-11-17  5000     0      10
    1       1   7698   BLAKE    MANAGER  7839 1981-05-01  2850     0      30
    2       2   7782   CLARK    MANAGER  7839 1981-05-09  2450     0      10
    3       3   7566   JONES    MANAGER  7839 1981-04-01  2975     0      20
    4       4   7654  MARTIN   SALESMAN  7698 1981-09-10  1250  1400      30
    5       5   7499   ALLEN   SALESMAN  7698 1981-02-11  1600   300      30
    6       6   7844  TURNER   SALESMAN  7698 1981-08-21  1500     0      30
    7       7   7900   JAMES      CLERK  7698 1981-12-11   950     0      30
    8       8   7521    WARD   SALESMAN  7698 1981-02-23  1250   500      30
    9       9   7902    FORD    ANALYST  7566 1981-12-11  3000     0      20
    10     10   7369   SMITH      CLERK  7902 1980-12-09   800     0      20
    11     11   7788   SCOTT    ANALYST  7566 1982-12-22  3000     0      20
    12     12   7876   ADAMS      CLERK  7788 1983-01-15  1100     0      20
    13     13   7934  MILLER      CLERK  7782 1982-01-11  1300     0      10
    
    jonessal = emp.ix[emp['ename'] == 'JONES', 'sal'].iat[0]
    print (jonessal)
    2975
    empename = emp.ix[emp['sal'] > jonessal, ['ename','sal']]
    print (empename)
        ename   sal
    0    KING  5000
    9    FORD  3000
    11  SCOTT  3000
    

    【讨论】:

    • 感谢您的回答。下面代码的结果也是显示 NaN。 jonessal = emp[['sal']][emp['ename']=='JONES'] empename = emp[['ename','sal']][emp['sal'] > jonessal] print(empename )
    • 哎呀,对不起。一个可能的解决方案在另一个答案中描述ayhan,我使用iat 添加其他解决方案 - 选择Series 中的第一个值和一个值。
    【解决方案3】:

    您对DataFrame.from_csv 的调用不正确。默认情况下,它需要逗号“,”作为字段分隔符:

    http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.from_csv.html

    Parameters:
      sep : string, default ‘,’
    Field delimiter
    

    但是你的 csv 不是逗号分隔的,而是制表符分隔的。

    尝试在 from_csv 调用中添加sep='\t' 参数:pd.DataFrame.from_csv("D:\R data\emp.csv",sep='\t')

    【讨论】:

    • 感谢您的回答。但是使用此代码的 emp.csv 是逗号分隔的。
    • yu,您是否在问题中未更改 emp.csv 文件?这里看起来像制表符分隔 - 列之间有空格和/或制表符。如果真的是逗号,请编辑您的问题并从emp.csv 文件中添加实际行(标题和十到二十行数据)。
    • 我编辑了我的帖子。 emp.csv 文件的列之间的逗号。但显示为 NaN
    • 于,第一列后面没有逗号:“0 7839, KING,”
    • 你,你可以接受解决你问题的答案(请在问题中给出真实的输入文件,我还是不明白标题行中是否有逗号)
    猜你喜欢
    • 2017-08-18
    • 2021-10-08
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 2020-03-21
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多