如何根据列值的长度从pandas数据帧中删除一行?

时间:2017-03-20 02:47:03

标签: python pandas dataframe string-length

在以下df = alfa beta ceta a,b,c c,d,e g,e,h a,b d,e,f g,h,k j,k c,k,l f,k,n 中:

df = df[['alfa'].str.split(',').map(len) < 3]

如何删除alfa的列值超过2个元素的行?这可以使用长度函数来完成,我知道但没有找到具体的答案。

CREATE TABLE CUSTOMER (
C_CUSTOMER_ID  INTEGER(3)   NOT NULL  UNIQUE,
C_LNAME        VARCHAR(20)  NOT NULL,
C_FNAME        VARCHAR(15)  NOT NULL,
C_ADDRESS      VARCHAR(50)  NOT NULL,
C_CITY         VARCHAR(25)  NOT NULL,
C_STATE        CHAR(2)      NOT NULL,
C_ZIP          CHAR(5)      NOT NULL,
C_HOME_PHONE   CHAR(10)     NOT NULL,
C_MOB_PHONE    CHAR(10),
C_OTH_PHONE    CHAR(10),
PRIMARY KEY (C_CUSTOMER_ID));

CREATE TABLE ORDER_TABLE (
ORDER_ID       INTEGER(5)   NOT NULL  UNIQUE,
ORDER_DATE     DATETIME     NOT NULL,
ORDER_NOTES    VARCHAR(250) NOT NULL,
C_CUSTOMER_ID  INTEGER,
PRIMARY KEY (ORDER_ID),
FOREIGN KEY (C_CUSTOMER_ID) REFERENCES CUSTOMER(C_CUSTOMER_ID));

CREATE TABLE DONUT (
DONUT_ID     INTEGER(3)       NOT NULL  UNIQUE,
DONUT_NAME   VARCHAR(15)  NOT NULL,
DONUT_DESCR  VARCHAR(50)  NOT NULL,
DONUT_PRICE  DECIMAL(2,2) NOT NULL,
PRIMARY KEY (DONUT_ID));

CREATE TABLE LINE_ITEMS (
DONUT_ID   INTEGER    NOT NULL,
ORDER_ID   INTEGER    NOT NULL,
QUANTITY INTEGER(3) NOT NULL,
PRIMARY KEY (DONUT_ID, ORDER_ID),
FOREIGN KEY (DONUT_ID) REFERENCES DONUT(DONUT_ID),
FOREIGN KEY (ORDER_ID) REFERENCES ORDER_TABLE(ORDER_ID));

5 个答案:

答案 0 :(得分:5)

您可以使用Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '__file__' is not defined

依次对每一行进行测试
pandas.DataFrame.apply()

给出:

print(df[df['alfa'].apply(lambda x: len(x.split(',')) < 3)])

答案 1 :(得分:3)

这是@ NickilMaveli答案的numpy版本。

mask = np.core.defchararray.count(df.alfa.values.astype(str), ',') <= 1
pd.DataFrame(df.values[mask], df.index[mask], df.columns)

  alfa   beta   ceta
1  a,b  d,e,f  g,h,k
2  j,k  c,k,l  f,k,n

天真的时间

enter image description here

答案 2 :(得分:2)

这是怎么回事?

df = df[df['alpha'].str.split(',', expand=True)[2].isnull()]

使用expand=True创建一个新数据框,列表中的每个项目都有一列。如果列表包含三个或更多项,则第三列将具有非空值。

此方法的一个问题是,如果列表中没有一个包含三个或更多项,则选择列[2]将导致KeyError。基于此,使用@Stephen Rauch发布的解决方案更安全。

答案 3 :(得分:2)

至少有两种方法可以对给定的DF进行子集化:

1)在逗号分隔符上拆分,然后计算结果list的长度:

df[df['alfa'].str.split(",").str.len().lt(3)]

2)计算逗号数量,并在结果中加1以计算最后一个字符:

df[df['alfa'].str.count(",").add(1).lt(3)] 

两者都产生:

enter image description here

答案 4 :(得分:1)

这是一个最容易记住并且仍然拥抱数据框架的选项,它是熊猫的“流血之心”:

1)在数据框中创建一个新列,其长度为:

df['length'] = df.alfa.str.len()

2)使用新栏目的索引:

df = df[df.length < 3]

然后与上述时间的比较,在这种情况下并不真正相关,因为数据非常小,并且通常不如你记得如何做某事而不必打断你的工作流程:

第1步:

%timeit df['length'] = df.alfa.str.len()

每回路359μs±6.83μs(平均值±标准偏差,7次运行,每次1000次循环)

第2步:

df = df[df.length < 3]

每回路627μs±76.9μs(平均值±标准偏差,7次运行,每次1000次循环)

好消息是,当规模增长时,时间不会线性增长。例如,对30,000行数据执行相同操作大约需要3ms(因此10,000x数据,速度提高3倍)。 Pandas DataFrame就像一列火车,需要精力才能实现它(对绝对比较的小东西来说不是很好,但客观上并不重要......因为小数据事物很快就会很快)。