使用pandas从csv中删除特定行

时间:2017-04-25 01:22:33

标签: python-3.x csv pandas numpy

我有一个csv文件,格式如下所示:enter image description here

我编写了以下代码来读取文件,并随机删除转向值为0的行。我想保留10%的转向值为0的行。

printf "%s" "$str" \
| awk '{ uniq_col_1=4; uniq_col_2=8; printf "%5s %15s %s\n", uniq_col_1, uniq_col_2, $0 }' \
| uniq -f 0 -w 5 \
| uniq -f 1 -w 15 \
| awk '{ $1=$2=""; gsub(/^ */, "", $0); printf "%s\n", $0 }'

但是,我收到以下错误:

  

df = df.drop(df.query('steering == 0')。sample(frac = 0.90).index)

     

locs = rs.choice(axis_length,size = n,replace = replace,p = weights)

     

文件“mtrand.pyx”,第1104行,在mtrand.RandomState.choice中   (numpy的/无规/ mtrand / mtrand.c:17062)

     

ValueError:a必须大于0

你们能帮助我吗?

3 个答案:

答案 0 :(得分:2)

这是一种单线方式,使用concat()sample()

import numpy as np
import pandas as pd

# first, some sample data

# generate filename fields
positions = ['center','left','right']
N = 100
fnames = ['{}_{}.jpg'.format(loc, np.random.randint(100)) for loc in np.repeat(positions, N)]
df = pd.DataFrame(np.array(fnames).reshape(3,100).T, columns=positions)

# generate numeric fields
values = [0,1,2,3,4]
probas = [.5,.2,.1,.1,.1]
df['steering'] = np.random.choice(values, p=probas, size=N)
df['throttle'] = np.random.choice(values, p=probas, size=N)
df['brake'] = np.random.choice(values, p=probas, size=N)

print(df.shape)
(100,3)

样本输出的前几行:

df.head()
           center         left         right  steering  throttle  brake
0   center_72.jpg  left_26.jpg  right_59.jpg         3         3      0
1   center_75.jpg  left_68.jpg  right_26.jpg         0         0      2
2   center_29.jpg   left_8.jpg  right_88.jpg         0         1      0
3   center_22.jpg  left_26.jpg  right_23.jpg         1         0      0
4   center_88.jpg   left_0.jpg  right_56.jpg         4         1      0
5   center_93.jpg  left_18.jpg  right_15.jpg         0         0      0

现在使用steering==0删除除了10%的所有行:

newdf = pd.concat([df.loc[df.steering!=0], 
                   df.loc[df.steering==0].sample(frac=0.1)])

根据我在此示例中使用的概率加权,您会在newdf中看到50-60个剩余条目之间的某个位置,剩余大约5个steering==0个案例。

答案 1 :(得分:2)

示例DataFrame built with @andrew_reece's code

In [9]: df
Out[9]:
           center         left         right  steering  throttle  brake
0   center_54.jpg  left_75.jpg  right_39.jpg         1         0      0
1   center_20.jpg  left_81.jpg  right_49.jpg         3         1      1
2   center_34.jpg  left_96.jpg  right_11.jpg         0         4      2
3   center_98.jpg  left_87.jpg  right_34.jpg         0         0      0
4   center_67.jpg  left_12.jpg  right_28.jpg         1         1      0
5   center_11.jpg  left_25.jpg  right_94.jpg         2         1      0
6   center_66.jpg  left_27.jpg  right_52.jpg         1         3      3
7   center_18.jpg  left_50.jpg  right_17.jpg         0         0      4
8   center_60.jpg  left_25.jpg  right_28.jpg         2         4      1
9   center_98.jpg  left_97.jpg  right_55.jpg         3         3      0
..            ...          ...           ...       ...       ...    ...
90  center_31.jpg  left_90.jpg  right_43.jpg         0         1      0
91  center_29.jpg   left_7.jpg  right_30.jpg         3         0      0
92  center_37.jpg  left_10.jpg  right_15.jpg         1         0      0
93  center_18.jpg   left_1.jpg  right_83.jpg         3         1      1
94  center_96.jpg  left_20.jpg  right_56.jpg         3         0      0
95  center_37.jpg  left_40.jpg  right_38.jpg         0         3      1
96  center_73.jpg  left_86.jpg  right_71.jpg         0         1      0
97  center_85.jpg  left_31.jpg   right_0.jpg         3         0      4
98  center_34.jpg  left_52.jpg  right_40.jpg         0         0      2
99  center_91.jpg  left_46.jpg  right_17.jpg         0         0      0

[100 rows x 6 columns]

In [10]: df.steering.value_counts()
Out[10]:
0    43    # NOTE: 43 zeros
1    18
2    15
4    12
3    12
Name: steering, dtype: int64

In [11]: df.shape
Out[11]: (100, 6)

您的解决方案(未更改):

In [12]: df = df.drop(df.query('steering==0').sample(frac=0.90).index)

In [13]: df.steering.value_counts()
Out[13]:
1    18
2    15
4    12
3    12
0     4        # NOTE: 4 zeros (~10% from 43)
Name: steering, dtype: int64

In [14]: df.shape
Out[14]: (61, 6)

注意:确保steering列包含数字dtype!如果它是一个字符串(对象),那么您需要更改代码,如下所示:

df = df.drop(df.query('steering=="0"').sample(frac=0.90).index)
#  NOTE:                         ^ ^

之后,您可以将修改后的(简化的)DataFrame保存为CSV:

df.to_csv('/path/to/filename.csv', index=False)

答案 2 :(得分:1)

使用steering上的掩码和随机数应该有效:

df = df[(df.steering != 0) | (np.random.rand(len(df)) < 0.1)]

这会产生一些额外的随机值,但它很好而且紧凑。

编辑:那就是说,我尝试了你的示例代码,它也运行良好。我的猜测是错误来自于df.query()语句返回空数据帧的事实,这可能意味着"sample"列不包含任何零,或者该列被读为字符串而不是数字。尝试在运行上述代码段之前将列转换为整数。