เมื่อลบคอลัมน์ใน DataFrame ฉันใช้:
del df['column_name']
และใช้งานได้ดี ทำไมฉันไม่สามารถใช้สิ่งต่อไปนี้
del df.column_name
เนื่องจากเป็นไปได้ที่จะเข้าถึงคอลัมน์ / ซีรี่ส์ในขณะที่df.column_nameฉันคาดว่าสิ่งนี้จะทำงาน
เมื่อลบคอลัมน์ใน DataFrame ฉันใช้:
del df['column_name']
และใช้งานได้ดี ทำไมฉันไม่สามารถใช้สิ่งต่อไปนี้
del df.column_name
เนื่องจากเป็นไปได้ที่จะเข้าถึงคอลัมน์ / ซีรี่ส์ในขณะที่df.column_nameฉันคาดว่าสิ่งนี้จะทำงาน
คำตอบ:
ในขณะที่คุณคาดเดาไวยากรณ์ที่ถูกต้องคือ
del df['column_name']
เป็นการยากที่จะทำให้del df.column_nameงานง่ายขึ้นเนื่องจากข้อ จำกัด ทางไวยากรณ์ใน Python del df[name]ได้รับการแปลdf.__delitem__(name)ภายใต้หน้ากากโดย Python
class A(object): def __init__(self): self.var = 1ชุดชั้นขึ้นมาแล้วa = A(); del a.varทำงานได้ดี ...
del df[name]มันจะได้รับการแปลdf.__delitem__(name)ซึ่งเป็นวิธีการที่ DataFrame สามารถนำไปใช้และแก้ไขตามความต้องการของมัน ในกรณีของdel df.nameตัวแปรสมาชิกจะถูกลบโดยไม่มีโอกาสสำหรับการเรียกใช้รหัสที่กำหนดเอง ลองพิจารณาตัวอย่างของคุณเองคุณจะได้del a.varผลการพิมพ์ "การลบตัวแปร" หรือไม่? ถ้าทำได้โปรดบอกฉันทีว่า ฉันทำไม่ได้ :)
pandasนักพัฒนาไม่ได้ทำแต่นั่นไม่ได้หมายความว่ามันยากที่จะทำ
วิธีที่ดีที่สุดในการทำเช่นนี้คือการใช้แพนด้าdrop:
df = df.drop('column_name', 1)
โดยที่1คือหมายเลขแกน ( 0สำหรับแถวและ1สำหรับคอลัมน์)
หากต้องการลบคอลัมน์โดยไม่ต้องมอบหมายใหม่dfคุณสามารถทำได้:
df.drop('column_name', axis=1, inplace=True)
สุดท้ายหากต้องการลดจำนวนคอลัมน์แทนโดยใช้ป้ายกำกับคอลัมน์ให้ลองใช้วิธีนี้เพื่อลบเช่นคอลัมน์ที่ 1, 2 และ 4:
df = df.drop(df.columns[[0, 1, 3]], axis=1) # df.columns is zero-based pd.Index
ทำงานกับไวยากรณ์ "text" สำหรับคอลัมน์ด้วย:
df.drop(['column_nameA', 'column_nameB'], axis=1, inplace=True)
delสำหรับเหตุผลบางอย่าง?
dropover delคือdropช่วยให้คุณสามารถวางหลายคอลัมน์พร้อมกันดำเนินการ inplace หรือไม่และยังลบบันทึกตามแกนใด ๆ (โดยเฉพาะอย่างยิ่งมีประโยชน์สำหรับเมทริกซ์ 3 มิติหรือPanel)
ใช้:
columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)
การดำเนินการนี้จะลบหนึ่งหรือหลายคอลัมน์ในตำแหน่ง โปรดทราบว่าinplace=Trueมีการเพิ่มใน pandas v0.13 และจะไม่ทำงานกับรุ่นเก่ากว่า คุณจะต้องกำหนดผลลัพธ์กลับมาในกรณีนั้น:
df = df.drop(columns, axis=1)
df.drop(list,inplace=True,axis=1)
del- สามารถดร็อปมากกว่าหนึ่งคอลัมน์พร้อมกัน
ลบคอลัมน์แรกคอลัมน์ที่สองและสี่:
df.drop(df.columns[[0,1,3]], axis=1, inplace=True)
ลบคอลัมน์แรก:
df.drop(df.columns[[0]], axis=1, inplace=True)
มีพารามิเตอร์ทางเลือกinplaceเพื่อให้ข้อมูลต้นฉบับสามารถแก้ไขได้โดยไม่ต้องสร้างสำเนา
ลบคอลัมน์column-name:
df.pop('column-name')
df = DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6]), ('C', [7,8, 9])], orient='index', columns=['one', 'two', 'three'])
print df:
one two three
A 1 2 3
B 4 5 6
C 7 8 9
df.drop(df.columns[[0]], axis=1, inplace=True)
print df:
two three
A 2 3
B 5 6
C 8 9
three = df.pop('three')
print df:
two
A 2
B 5
C 8
df.T.pop('A')
dfที่ไม่ได้ปรับเปลี่ยนเดิม คุณสามารถทำได้df = df.T; df.pop(index); df = df.Tแต่ดูเหมือนว่าจะมากเกินไป
df.drop(df.columns[[0]], axis=1, inplace=True)มันจะไม่เพียงพอdf.drop([0], axis=1)หรือ?
0ก็df.drop(0, axis=1)ใช้งานได้ดี แต่ถ้าไม่ทราบชื่อคอลัมน์และต้องการลบคอลัมน์แรกก็จำเป็นต้องdf.drop(df.columns[[0]], axis=1, inplace=True)เลือกคอลัมน์แรกตามตำแหน่งและวาง
คำถามจริงที่โพสต์พลาดโดยคำตอบส่วนใหญ่ที่นี่คือ:
del df.column_nameไม่ได้ตอนแรกเราต้องเข้าใจปัญหาที่เกิดขึ้นซึ่งเราต้องดำน้ำในวิธีมายากลหลาม
ในขณะที่เวสต์ชี้ให้เห็นในคำตอบของเขาdel df['column']แมปไปยังวิธีการของเวทมนตร์ หลามdf.__delitem__('column')ซึ่งถูกนำมาใช้ในแพนด้าเพื่อวางคอลัมน์
อย่างไรก็ตามดังที่ได้กล่าวไว้ในลิงค์ด้านบนเกี่ยวกับวิธีการของเวทมนต์ :
ในความเป็นจริงแล้ว
__del__แทบจะไม่เคยถูกใช้เพราะสถานการณ์ที่ล่อแหลมซึ่งมันถูกเรียกว่า; ใช้ด้วยความระมัดระวัง!
คุณสามารถโต้แย้งว่าdel df['column_name']ไม่ควรใช้หรือส่งเสริมและดังนั้นจึงdel df.column_nameไม่ควรพิจารณา
แต่ในทางทฤษฎีdel df.column_nameอาจจะ implemeted การทำงานในหมีแพนด้าใช้วิธีมายากล อย่างไรก็ตามนี่จะแนะนำปัญหาบางอย่างปัญหาที่การนำไปใช้มีอยู่แล้ว แต่ในระดับที่น้อยกว่า__delattr__del df['column_name']
จะเกิดอะไรขึ้นถ้าฉันกำหนดคอลัมน์ในชื่อไฟล์ที่เรียกว่า "dtypes" หรือ "คอลัมน์"
จากนั้นสมมติว่าฉันต้องการลบคอลัมน์เหล่านี้
del df.dtypesจะทำให้__delattr__วิธีการสับสนราวกับว่ามันควรจะลบแอตทริบิวต์ "dtypes" หรือคอลัมน์ "dtypes"
.ix, .locหรือ.ilocวิธีการคุณไม่สามารถทำได้del df.column_nameเพราะหมีแพนด้ามีสถาปัตยกรรมที่ค่อนข้างโตและต้องได้รับการพิจารณาใหม่เพื่อให้ความไม่ลงรอยกันทางปัญญาประเภทนี้ไม่เกิดขึ้นกับผู้ใช้
อย่าใช้ df.column_name มันอาจจะสวย แต่ก็ทำให้เกิดความไม่ลงรอยกันทางปัญญา
การลบคอลัมน์มีหลายวิธี
ควรมีอย่างน้อยหนึ่งวิธีที่ชัดเจนกว่าที่จะทำ
คอลัมน์บางครั้งเป็นคุณลักษณะ แต่บางครั้งก็ไม่ใช่
กรณีพิเศษไม่พิเศษพอที่จะทำลายกฎ
ไม่del df.dtypesลบ dtypes แอตทริบิวต์หรือ dtypes คอลัมน์?
ในการเผชิญกับความกำกวมปฏิเสธสิ่งล่อใจที่จะคาดเดา
__del__แทบจะไม่เคยถูกใช้เพราะสถานการณ์ที่ล่อแหลมภายใต้มันถูกเรียก; ใช้มันด้วยความระมัดระวัง!" __delattr__ไม่เกี่ยวข้องอย่างสมบูรณ์ที่นี่เป็นวิธีการที่ถูกนำมาใช้ที่นี่
delbuiltin ที่มีความหมายไม่ใช่.__del__วิธีอินสแตนซ์ delbuiltin กำลังทำแผนที่ไป__delattr__และ__delitem__ซึ่งเป็นสิ่งที่ฉันสร้างอาร์กิวเมนต์ของฉันใน ดังนั้นคุณอาจต้องการอ่านสิ่งที่ฉันเขียนใหม่
__... __ถูกตีความว่าเป็นมาร์กอัปตัวหนาโดย StackExchange
นอกจากนี้ที่ดีคือความสามารถในการวางคอลัมน์เฉพาะในกรณีที่พวกเขามีอยู่ วิธีนี้คุณสามารถครอบคลุมกรณีการใช้งานเพิ่มเติมและมันจะวางคอลัมน์ที่มีอยู่จากป้ายชื่อที่ส่งผ่านไปเท่านั้น:
เพียงเพิ่มข้อผิดพลาด = 'ละเว้น'ตัวอย่างเช่น:
df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
จากเวอร์ชั่น 0.16.1 คุณสามารถทำได้
df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')
errors= 'ignore') df.drop(['column_1','column_2'], axis=1 , inplace=True,errors= 'ignore')หากต้องการแอปพลิเคชั่น!
เป็นแนวปฏิบัติที่ดีที่จะใช้[]สัญลักษณ์ เหตุผลหนึ่งคือสัญกรณ์แอตทริบิวต์ ( df.column_name) นั้นใช้ไม่ได้กับดัชนีที่มีหมายเลข
In [1]: df = DataFrame([[1, 2, 3], [4, 5, 6]])
In [2]: df[1]
Out[2]:
0 2
1 5
Name: 1
In [3]: df.1
File "<ipython-input-3-e4803c0d1066>", line 1
df.1
^
SyntaxError: invalid syntax
Pandas เวอร์ชั่น 0.21 ได้เปลี่ยนdropวิธีการเล็กน้อยเพื่อรวมทั้งindexและcolumnsพารามิเตอร์เพื่อให้ตรงกับลายเซ็นของrenameและreindexวิธีการ
df.drop(columns=['column_a', 'column_c'])
โดยส่วนตัวแล้วฉันชอบใช้axisพารามิเตอร์เพื่อแสดงคอลัมน์หรือดัชนีเนื่องจากเป็นพารามิเตอร์คำหลักที่ใช้ในเกือบทุกวิธีของแพนด้า แต่ตอนนี้คุณมีตัวเลือกเพิ่มเติมในเวอร์ชัน 0.21
ใน pandas 0.16.1+ คุณสามารถวางคอลัมน์ได้หากมีอยู่ต่อโซลูชันที่โพสต์โดย @eiTanLaVi ก่อนหน้าเวอร์ชันนั้นคุณสามารถได้รับผลลัพธ์เดียวกันผ่านรายการความเข้าใจแบบมีเงื่อนไข:
df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df],
axis=1, inplace=True)
ความพยายามมากมายในการค้นหาโซลูชันที่มีประสิทธิภาพยิ่งขึ้นเล็กน้อย ยากที่จะพิสูจน์ความซับซ้อนที่เพิ่มขึ้นในขณะที่เสียสละความเรียบง่ายของdf.drop(dlst, 1, errors='ignore')
df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)
บทนำการ
ลบคอลัมน์นั้นมีความหมายเหมือนกับการเลือกคอลัมน์อื่น ๆ ฉันจะแสดงวิธีการเพิ่มเติมที่ควรพิจารณา
ฉันจะมุ่งเน้นไปที่โซลูชันทั่วไปของการลบหลายคอลัมน์พร้อมกันและอนุญาตให้พยายามลบคอลัมน์ที่ไม่มีอยู่
การใช้โซลูชันเหล่านี้เป็นเรื่องทั่วไปและจะทำงานในกรณีที่ง่ายเช่นกัน
ตั้งค่า
พิจารณาpd.DataFrame dfและรายการที่จะลบ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']
ผลลัพธ์ควรมีลักษณะดังนี้:
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
เนื่องจากฉันกำลังทำการลบคอลัมน์เพื่อเลือกคอลัมน์อื่นฉันจะแยกมันออกเป็นสองประเภท:
เราเริ่มต้นด้วยการผลิตรายการ / อาเรย์ของป้ายกำกับที่แสดงถึงคอลัมน์ที่เราต้องการเก็บและไม่มีคอลัมน์ที่เราต้องการลบ
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']
คอลัมน์จากป้ายกำกับ
เพื่อเปรียบเทียบกระบวนการคัดเลือกให้ถือว่า:
cols = [x for x in df.columns.values.tolist() if x not in dlst]
จากนั้นเราสามารถประเมิน
df.loc[:, cols]df[cols]df.reindex(columns=cols)df.reindex_axis(cols, 1)ซึ่งทั้งหมดประเมินว่า:
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
เราสามารถสร้างอาร์เรย์ / รายการบูลีนสำหรับการแบ่งส่วน
~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)คอลัมน์จากบูลีน
เพื่อการเปรียบเทียบ
bools = [x not in dlst for x in df.columns.values.tolist()]
df.loc[: bools]ซึ่งทั้งหมดประเมินว่า:
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
เวลาที่แข็งแกร่ง
ฟังก์ชั่น
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)
การทดสอบ
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()
df.drop(dlst, 1, errors='ignore')นี้จะสัมพันธ์กับเวลาที่ใช้ในการทำงาน ดูเหมือนว่าหลังจากนั้นเราก็ปรับปรุงประสิทธิภาพเพียงเล็กน้อยเท่านั้น
หากความจริงแล้วทางออกที่ดีที่สุดใช้reindexหรือreindex_axisแฮ็list(set(df.columns.values.tolist()).difference(dlst))ค สนิทที่สองและยังคงเป็นอย่างดีกว่าเล็กน้อยคือdropnp.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
ไวยากรณ์จุดทำงานใน JavaScript แต่ไม่ได้อยู่ใน Python
del df['column_name']del df['column_name'] หรือ del df.column_nameหาก dataframe ดั้งเดิมของคุณdfไม่ใหญ่เกินไปคุณไม่มีข้อ จำกัด ด้านหน่วยความจำและคุณต้องการเก็บคอลัมน์ไว้สองสามคอลัมน์จากนั้นคุณอาจสร้าง dataframe ใหม่ด้วยคอลัมน์ที่คุณต้องการเท่านั้น:
new_df = df[['spam', 'sausage']]
เราสามารถลบหรือลบคอลัมน์ที่ระบุหรือคอลัมน์ sprcified โดยวิธีการลดลง ()
สมมติว่าdfเป็น dataframe
คอลัมน์ที่จะลบ = column0
รหัส:
df = df.drop(column0, axis=1)
หากต้องการลบหลายคอลัมน์ col1, col2, . . , คอลัมน์, เราต้องแทรกคอลัมน์ทั้งหมดที่จำเป็นต้องลบออกในรายการ จากนั้นลบออกโดยวิธีการปล่อย ()
รหัส:
df = df.drop([col1, col2, . . . , coln], axis=1)
ฉันหวังว่ามันจะเป็นประโยชน์
df = df.drop([col1, col2, . . . , coln], axis=1)มันไม่ทำงานถ้าฉันระบุชื่อตัวแปรแทนที่ col1, col2 เป็นต้นฉันได้รับคอลัมน์ข้อผิดพลาดไม่ได้อยู่ในแกนเมื่อมันมีอยู่แน่นอน @Littin คุณช่วยได้ไหม?
อีกวิธีในการลบคอลัมน์ใน Pandas DataFrame
หากคุณไม่ได้มองหาการลบในสถานที่คุณสามารถสร้าง DataFrame ใหม่โดยการระบุคอลัมน์โดยใช้DataFrame(...)ฟังก์ชั่นเป็น
my_dict = { 'name' : ['a','b','c','d'], 'age' : [10,20,25,22], 'designation' : ['CEO', 'VP', 'MD', 'CEO']}
df = pd.DataFrame(my_dict)
สร้าง DataFrame ใหม่เป็น
newdf = pd.DataFrame(df, columns=['name', 'age'])
คุณจะได้รับผลลัพธ์ที่ดีเท่าที่คุณจะได้รับด้วยเดล / ดรอป