Tôi có một số dữ liệu và khi nhập dữ liệu, tôi nhận được các cột không cần thiết sau. Tôi đang tìm một cách dễ dàng để xóa tất cả những dữ liệu này
'Unnamed: 24', 'Unnamed: 25', 'Unnamed: 26', 'Unnamed: 27',
'Unnamed: 28', 'Unnamed: 29', 'Unnamed: 30', 'Unnamed: 31',
'Unnamed: 32', 'Unnamed: 33', 'Unnamed: 34', 'Unnamed: 35',
'Unnamed: 36', 'Unnamed: 37', 'Unnamed: 38', 'Unnamed: 39',
'Unnamed: 40', 'Unnamed: 41', 'Unnamed: 42', 'Unnamed: 43',
'Unnamed: 44', 'Unnamed: 45', 'Unnamed: 46', 'Unnamed: 47',
'Unnamed: 48', 'Unnamed: 49', 'Unnamed: 50', 'Unnamed: 51',
'Unnamed: 52', 'Unnamed: 53', 'Unnamed: 54', 'Unnamed: 55',
'Unnamed: 56', 'Unnamed: 57', 'Unnamed: 58', 'Unnamed: 59',
'Unnamed: 60'
Chúng được lập chỉ mục bằng cách lập chỉ mục 0, vì vậy tôi đã thử một cái gì đó như
df.drop[df.columns[[22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32 ,55]], axis=1, inplace=True]
Nhưng điều này không hiệu quả lắm. Tôi đã thử viết một số vòng lặp for nhưng điều này khiến tôi coi là hành vi xấu của Gấu trúc. Do đó tôi đặt câu hỏi ở đây.
Tôi đã thấy một số ví dụ tương tự [ Thả nhiều cột gấu trúc ] nhưng điều này không trả lời câu hỏi của tôi.
102 hữu ích 4 bình luận 195k xem chia sẻ
TL; DR
Rất nhiều nỗ lực để tìm một giải pháp hiệu quả hơn một chút. Khó có thể biện minh cho sự phức tạp được thêm vào trong khi hy sinh tính đơn giản của df.drop[dlst, 1, errors='ignore']
df.reindex_axis[np.setdiff1d[df.columns.values, dlst], 1]
Lời nói đầu
[.__.] Xóa một cột về mặt ngữ nghĩa giống như chọn các cột khác. Tôi sẽ chỉ ra một vài phương pháp bổ sung để xem xét.
Tôi cũng sẽ tập trung vào giải pháp chung là xóa nhiều cột cùng một lúc và cho phép thử xóa các cột không có mặt.
Sử dụng các giải pháp này là chung và sẽ làm việc cho trường hợp đơn giản là tốt.
Cài đặt
[.__.] Hãy xem xét pd.DataFrame
df
và liệt kê để xóa dlst
df = pd.DataFrame[dict[Zip['ABCDEFGHIJ', range[1, 11]]], range[3]]
dlst = list['HIJKLM']
df
A B C D E F G H I J
0 1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 1 2 3 4 5 6 7 8 9 10
dlst
['H', 'I', 'J', 'K', 'L', 'M']
Kết quả sẽ giống như:
df.drop[dlst, 1, errors='ignore']
A B C D E F G
0 1 2 3 4 5 6 7
1 1 2 3 4 5 6 7
2 1 2 3 4 5 6 7
Vì tôi đang cân bằng việc xóa một cột để chọn các cột khác, tôi sẽ chia nó thành hai loại:
- Lựa chọn nhãn
- Lựa chọn Boolean
Lựa chọn nhãn
Chúng tôi bắt đầu bằng cách sản xuất danh sách/mảng nhãn đại diện cho các cột chúng tôi muốn giữ và không có các cột chúng tôi muốn xóa.
df.columns.difference[dlst]
Index[['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object']
np.setdiff1d[df.columns.values, dlst]
array[['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object]
df.columns.drop[dlst, errors='ignore']
Index[['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object']
list[set[df.columns.values.tolist[]].difference[dlst]]
# does not preserve order ['E', 'D', 'B', 'F', 'G', 'A', 'C']
[x for x in df.columns.values.tolist[] if x not in dlst]
['A', 'B', 'C', 'D', 'E', 'F', 'G']
Cột từ Nhãn
[.___.] Để so sánh quá trình lựa chọn, giả sử:
cols = [x for x in df.columns.values.tolist[] if x not in dlst]
Sau đó chúng ta có thể đánh giá
df.loc[:, cols]
df[cols]
df.reindex[columns=cols]
df.reindex_axis[cols, 1]
Mà tất cả đánh giá để:
A B C D E F G
0 1 2 3 4 5 6 7
1 1 2 3 4 5 6 7
2 1 2 3 4 5 6 7
Lát Boolean
Chúng ta có thể xây dựng một mảng/danh sách các booleans để cắt
~df.columns.isin[dlst]
~np.in1d[df.columns.values, dlst]
[x not in dlst for x in df.columns.values.tolist[]]
[df.columns.values[:, None] != dlst].all[1]
Cột từ Boolean
[.__.] Để so sánh
bools = [x not in dlst for x in df.columns.values.tolist[]]
df.loc[: bools]
Mà tất cả đánh giá để:
A B C D E F G
0 1 2 3 4 5 6 7
1 1 2 3 4 5 6 7
2 1 2 3 4 5 6 7
Thời gian mạnh mẽ
Hàm
setdiff1d = lambda df, dlst: np.setdiff1d[df.columns.values, dlst]
difference = lambda df, dlst: df.columns.difference[dlst]
columndrop = lambda df, dlst: df.columns.drop[dlst, errors='ignore']
setdifflst = lambda df, dlst: list[set[df.columns.values.tolist[]].difference[dlst]]
comprehension = lambda df, dlst: [x for x in df.columns.values.tolist[] if x not in dlst]
loc = lambda df, cols: df.loc[:, cols]
slc = lambda df, cols: df[cols]
ridx = lambda df, cols: df.reindex[columns=cols]
ridxa = lambda df, cols: df.reindex_axis[cols, 1]
isin = lambda df, dlst: ~df.columns.isin[dlst]
in1d = lambda df, dlst: ~np.in1d[df.columns.values, dlst]
comp = lambda df, dlst: [x not in dlst for x in df.columns.values.tolist[]]
brod = lambda df, dlst: [df.columns.values[:, None] != dlst].all[1]
Kiểm tra
res1 = pd.DataFrame[
index=pd.MultiIndex.from_product[[
'loc slc ridx ridxa'.split[],
'setdiff1d difference columndrop setdifflst comprehension'.split[],
], names=['Select', 'Label']],
columns=[10, 30, 100, 300, 1000],
dtype=float
]
res2 = pd.DataFrame[
index=pd.MultiIndex.from_product[[
'loc'.split[],
'isin in1d comp brod'.split[],
], names=['Select', 'Label']],
columns=[10, 30, 100, 300, 1000],
dtype=float
]
res = res1.append[res2].sort_index[]
dres = pd.Series[index=res.columns, name='drop']
for j in res.columns:
dlst = list[range[j]]
cols = list[range[j // 2, j + j // 2]]
d = pd.DataFrame[1, range[10], cols]
dres.at[j] = timeit['d.drop[dlst, 1, errors="ignore"]', 'from __main__ import d, dlst', number=100]
for s, l in res.index:
stmt = '{}[d, {}[d, dlst]]'.format[s, l]
setp = 'from __main__ import d, dlst, {}, {}'.format[s, l]
res.at[[s, l], j] = timeit[stmt, setp, number=100]
rs = res / dres
rs
10 30 100 300 1000
Select Label
loc brod 0.747373 0.861979 0.891144 1.284235 3.872157
columndrop 1.193983 1.292843 1.396841 1.484429 1.335733
comp 0.802036 0.732326 1.149397 3.473283 25.565922
comprehension 1.463503 1.568395 1.866441 4.421639 26.552276
difference 1.413010 1.460863 1.587594 1.568571 1.569735
in1d 0.818502 0.844374 0.994093 1.042360 1.076255
isin 1.008874 0.879706 1.021712 1.001119 0.964327
setdiff1d 1.352828 1.274061 1.483380 1.459986 1.466575
setdifflst 1.233332 1.444521 1.714199 1.797241 1.876425
ridx columndrop 0.903013 0.832814 0.949234 0.976366 0.982888
comprehension 0.777445 0.827151 1.108028 3.473164 25.528879
difference 1.086859 1.081396 1.293132 1.173044 1.237613
setdiff1d 0.946009 0.873169 0.900185 0.908194 1.036124
setdifflst 0.732964 0.823218 0.819748 0.990315 1.050910
ridxa columndrop 0.835254 0.774701 0.907105 0.908006 0.932754
comprehension 0.697749 0.762556 1.215225 3.510226 25.041832
difference 1.055099 1.010208 1.122005 1.119575 1.383065
setdiff1d 0.760716 0.725386 0.849949 0.879425 0.946460
setdifflst 0.710008 0.668108 0.778060 0.871766 0.939537
slc columndrop 1.268191 1.521264 2.646687 1.919423 1.981091
comprehension 0.856893 0.870365 1.290730 3.564219 26.208937
difference 1.470095 1.747211 2.886581 2.254690 2.050536
setdiff1d 1.098427 1.133476 1.466029 2.045965 3.123452
setdifflst 0.833700 0.846652 1.013061 1.110352 1.287831
fig, axes = plt.subplots[2, 2, figsize=[8, 6], sharey=True]
for i, [n, g] in enumerate[[[n, g.xs[n]] for n, g in rs.groupby['Select']]]:
ax = axes[i // 2, i % 2]
g.plot.bar[ax=ax, title=n]
ax.legend_.remove[]
fig.tight_layout[]
Điều này liên quan đến thời gian cần thiết để chạy
df.drop[dlst, 1, errors='ignore']
. Có vẻ như sau tất cả những nỗ lực đó, chúng tôi chỉ cải thiện hiệu suất một cách khiêm tốn.
Nếu thực tế, các giải pháp tốt nhất sử dụng reindex
hoặc reindex_axis
trên bản hack list[set[df.columns.values.tolist[]].difference[dlst]]
. Một thứ hai gần và vẫn rất tốt hơn so với drop
là np.setdiff1d
.
rs.idxmin[].pipe[
lambda x: pd.DataFrame[
dict[idx=x.values, val=rs.lookup[x.values, x.index]],
x.index
]
]
idx val
10 [ridx, setdifflst] 0.653431
30 [ridxa, setdifflst] 0.746143
100 [ridxa, setdifflst] 0.816207
300 [ridx, setdifflst] 0.780157
1000 [ridxa, setdifflst] 0.861622