จะเลือกแถวจากDataFrame
ค่าในคอลัมน์ใน Python Pandas ได้อย่างไร?
ใน SQL ฉันจะใช้:
SELECT *
FROM table
WHERE colume_name = some_value
ฉันพยายามดูเอกสารของแพนด้า แต่ไม่พบคำตอบในทันที
จะเลือกแถวจากDataFrame
ค่าในคอลัมน์ใน Python Pandas ได้อย่างไร?
ใน SQL ฉันจะใช้:
SELECT *
FROM table
WHERE colume_name = some_value
ฉันพยายามดูเอกสารของแพนด้า แต่ไม่พบคำตอบในทันที
คำตอบ:
ในการเลือกแถวที่ค่าคอลัมน์เท่ากับสเกลาร์some_value
ให้ใช้==
:
df.loc[df['column_name'] == some_value]
ในการเลือกแถวที่มีค่าคอลัมน์อยู่ใน iterable some_values
ให้ใช้isin
:
df.loc[df['column_name'].isin(some_values)]
รวมหลายเงื่อนไขเข้ากับ&
:
df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)]
หมายเหตุวงเล็บ เนื่องจาก ธกฎสำคัญประกอบ , &
ผูกแน่นกว่าและ<=
>=
ดังนั้นวงเล็บในตัวอย่างสุดท้ายจึงมีความจำเป็น โดยไม่ต้องใส่วงเล็บ
df['column_name'] >= A & df['column_name'] <= B
แยกเป็น
df['column_name'] >= (A & df['column_name']) <= B
ซึ่งส่งผลให้ค่าความจริงของซีรีส์เป็นข้อผิดพลาดที่ไม่ชัดเจน
ในการเลือกแถวที่ค่าคอลัมน์ไม่เท่ากัน some_value
ใช้!=
:
df.loc[df['column_name'] != some_value]
isin
ผลตอบแทนบูลีนซีรีส์เพื่อที่จะเลือกแถวที่มีค่าไม่ได้ในการsome_values
คัดค้านซีรีส์บูลโดยใช้~
:
df.loc[~df['column_name'].isin(some_values)]
ตัวอย่างเช่น,
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
# A B C D
# 0 foo one 0 0
# 1 bar one 1 2
# 2 foo two 2 4
# 3 bar three 3 6
# 4 foo two 4 8
# 5 bar two 5 10
# 6 foo one 6 12
# 7 foo three 7 14
print(df.loc[df['A'] == 'foo'])
อัตราผลตอบแทน
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
หากคุณมีหลายค่าที่คุณต้องการรวมให้ใส่ไว้ในรายการ (หรือโดยทั่วไปสามารถทำซ้ำได้) และใช้isin
:
print(df.loc[df['B'].isin(['one','three'])])
อัตราผลตอบแทน
A B C D
0 foo one 0 0
1 bar one 1 2
3 bar three 3 6
6 foo one 6 12
7 foo three 7 14
อย่างไรก็ตามโปรดทราบว่าหากคุณต้องการทำเช่นนี้หลายครั้งจะมีประสิทธิภาพมากกว่าในการสร้างดัชนีเป็นอันดับแรกจากนั้นใช้df.loc
:
df = df.set_index(['B'])
print(df.loc['one'])
อัตราผลตอบแทน
A C D
B
one foo 0 0
one bar 1 2
one foo 6 12
หรือเพื่อรวมหลายค่าจากการใช้ดัชนีdf.index.isin
:
df.loc[df.index.isin(['one','two'])]
อัตราผลตอบแทน
A C D
B
one foo 0 0
one bar 1 2
two foo 2 4
two foo 4 8
two bar 5 10
one foo 6 12
df.where(condition)
สภาพจะต้องมีรูปร่างเหมือนdf
กัน
df[df['column_name'] == some_value]
งานเราต้องเพิ่ม.loc
ที่นี่ทำไม
มีหลายวิธีในการเลือกแถวจากกรอบข้อมูลแพนด้า:
df[df['col'] == value
])df.iloc[...]
)df.xs(...)
)df.query(...)
APIด้านล่างฉันจะแสดงตัวอย่างของแต่ละข้อพร้อมคำแนะนำว่าควรใช้เทคนิคบางอย่างเมื่อใด สมมติว่าเกณฑ์ของเราคือคอลัมน์'A'
=='foo'
(หมายเหตุเกี่ยวกับประสิทธิภาพ: สำหรับแต่ละประเภทฐานเราสามารถทำให้สิ่งต่าง ๆ เรียบง่ายโดยใช้ pandas API หรือเราสามารถร่วมนอก API มักจะเป็นnumpy
และเร่งสิ่งต่าง ๆ ได้)
การตั้งค่า
สิ่งแรกที่เราต้องมีคือการระบุเงื่อนไขที่จะทำหน้าที่เป็นเกณฑ์ในการเลือกแถว เราจะเริ่มด้วยเคสของ OP column_name == some_value
และรวมเคสที่ใช้งานทั่วไปอื่น ๆ
การกู้ยืมจาก @unutbu:
import pandas as pd, numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
... การจัดทำดัชนีบูลีนต้องค้นหาค่าที่แท้จริงของแต่ละแถวของ'A'
คอลัมน์ให้เท่ากัน'foo'
จากนั้นใช้ค่าความจริงเหล่านั้นเพื่อระบุแถวที่จะเก็บ โดยทั่วไปแล้วเราจะตั้งชื่อชุดนี้ซึ่งมีค่าความจริงmask
มากมาย เราจะทำที่นี่เช่นกัน
mask = df['A'] == 'foo'
จากนั้นเราสามารถใช้หน้ากากนี้เพื่อเชือดหรือจัดทำดัชนีเฟรมข้อมูล
df[mask]
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
นี่เป็นวิธีที่ง่ายที่สุดวิธีหนึ่งในการทำภารกิจนี้ให้สำเร็จและหากประสิทธิภาพหรือความไม่เข้าใจเป็นปัญหานี่ควรเป็นวิธีที่คุณเลือก mask
แต่ถ้าผลการดำเนินงานเป็นกังวลแล้วคุณอาจต้องการที่จะต้องพิจารณาทางเลือกของการสร้าง
การจัดทำดัชนีตำแหน่ง ( df.iloc[...]
) มีกรณีการใช้งาน แต่นี่ไม่ใช่หนึ่งในนั้น ในการระบุตำแหน่งที่จะหั่นเราต้องทำการวิเคราะห์บูลีนแบบเดียวกับที่เราทำข้างต้น นี่ทำให้เราดำเนินการขั้นตอนพิเศษหนึ่งขั้นเพื่อให้งานเดียวกันสำเร็จ
mask = df['A'] == 'foo'
pos = np.flatnonzero(mask)
df.iloc[pos]
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
การจัดทำดัชนีฉลากอาจมีประโยชน์มาก แต่ในกรณีนี้เรากำลังทำงานอีกครั้งโดยไม่มีประโยชน์
df.set_index('A', append=True, drop=False).xs('foo', level=1)
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
df.query()
APIpd.DataFrame.query
เป็นวิธีที่หรูหรา / ใช้งานง่ายมากในการทำงานนี้ แต่มักจะช้ากว่า อย่างไรก็ตามหากคุณใส่ใจกับการกำหนดเวลาด้านล่างสำหรับข้อมูลขนาดใหญ่แบบสอบถามจะมีประสิทธิภาพมาก มากกว่าวิธีมาตรฐานและขนาดใกล้เคียงกันเป็นคำแนะนำที่ดีที่สุดของฉัน
df.query('A == "foo"')
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
การตั้งค่าของฉันคือการใช้ Boolean
mask
Boolean
mask
การปรับปรุงที่เกิดขึ้นจริงสามารถทำได้โดยการปรับเปลี่ยนวิธีการที่เราสร้างของเรา
mask
ทางเลือก 1
ใช้numpy
อาเรย์พื้นฐานและสละค่าใช้จ่ายในการสร้างอีกpd.Series
mask = df['A'].values == 'foo'
ฉันจะแสดงการทดสอบเวลาที่สมบูรณ์มากขึ้นในตอนท้าย แต่เพียงแค่ดูที่การเพิ่มประสิทธิภาพที่เราได้รับโดยใช้กรอบข้อมูลตัวอย่าง อันดับแรกเรามาดูความแตกต่างในการสร้างmask
%timeit mask = df['A'].values == 'foo'
%timeit mask = df['A'] == 'foo'
5.84 µs ± 195 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
166 µs ± 4.45 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
การประเมินmask
กับnumpy
อาร์เรย์เป็น ~ 30 ครั้งได้เร็วขึ้น นี่เป็นส่วนหนึ่งเนื่องจากการnumpy
ประเมินผลมักจะเร็วกว่า ส่วนหนึ่งเป็นเพราะการขาดค่าใช้จ่ายที่จำเป็นในการสร้างดัชนีและpd.Series
วัตถุที่สอดคล้องกัน
ต่อไปเราจะดูเวลาสำหรับการแบ่งส่วนหนึ่งmask
กับอีกชุด
mask = df['A'].values == 'foo'
%timeit df[mask]
mask = df['A'] == 'foo'
%timeit df[mask]
219 µs ± 12.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
239 µs ± 7.03 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ประสิทธิภาพที่เพิ่มขึ้นนั้นไม่ได้เด่นชัดเท่าที่ควร เราจะดูว่าการทดสอบนี้มีประสิทธิภาพมากกว่าหรือไม่
mask
ทางเลือก 2
เราสามารถสร้างกรอบข้อมูลใหม่ได้เช่นกัน มีข้อแม้ที่ยิ่งใหญ่เมื่อทำการสร้างดาต้าเฟรมใหม่ - คุณต้องดูแลdtypes
เมื่อทำเช่นนั้น!
แทนที่จะdf[mask]
ทำเช่นนี้เราจะทำ
pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)
หากกรอบข้อมูลเป็นประเภทผสมซึ่งเป็นตัวอย่างของเราแล้วเมื่อเราได้รับdf.values
อาร์เรย์ที่เกิดเป็นและดังนั้นคอลัมน์ทั้งหมดของกรอบข้อมูลใหม่จะเป็นdtype
object
dtype
object
ดังนั้นจึงจำเป็นต้องมีastype(df.dtypes)
และฆ่าประสิทธิภาพที่อาจเกิดขึ้นได้
%timeit df[m]
%timeit pd.DataFrame(df.values[mask], df.index[mask], df.columns).astype(df.dtypes)
216 µs ± 10.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.43 ms ± 39.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
อย่างไรก็ตามถ้า data frame นั้นไม่ใช่ชนิดแบบผสมนี่เป็นวิธีที่มีประโยชน์มากในการทำ
ป.ร. ให้ไว้
np.random.seed([3,1415])
d1 = pd.DataFrame(np.random.randint(10, size=(10, 5)), columns=list('ABCDE'))
d1
A B C D E
0 0 2 7 3 8
1 7 0 6 8 6
2 0 2 0 4 9
3 7 3 2 4 3
4 3 6 7 7 4
5 5 3 7 5 9
6 8 7 6 4 7
7 6 2 6 6 5
8 2 8 7 5 8
9 4 7 6 1 5
%%timeit
mask = d1['A'].values == 7
d1[mask]
179 µs ± 8.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
กับ
%%timeit
mask = d1['A'].values == 7
pd.DataFrame(d1.values[mask], d1.index[mask], d1.columns)
87 µs ± 5.12 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
เราลดเวลาลงครึ่งหนึ่ง
mask
ทางเลือก 3
@unutbu ยังแสดงให้เราเห็นถึงวิธีการใช้pd.Series.isin
ในการพิจารณาองค์ประกอบแต่ละอย่างของdf['A']
การอยู่ในชุดของค่า 'foo'
ประเมินนี้ถึงสิ่งเดียวกันถ้าชุดของค่านิยมของเราคือชุดของค่าหนึ่งคือ แต่ยังรวมถึงการรวมชุดของค่าที่ใหญ่กว่าถ้าจำเป็น ปรากฎว่านี่ยังค่อนข้างเร็วแม้ว่ามันจะเป็นคำตอบทั่วไป การสูญเสียที่แท้จริงเพียงอย่างเดียวคือการหยั่งรู้สำหรับผู้ที่ไม่คุ้นเคยกับแนวคิด
mask = df['A'].isin(['foo'])
df[mask]
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
อย่างไรก็ตามก่อนหน้านี้เราสามารถใช้numpy
เพื่อปรับปรุงประสิทธิภาพการทำงานโดยไม่ต้องเสียสละอะไรเลย เราจะใช้np.in1d
mask = np.in1d(df['A'].values, ['foo'])
df[mask]
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
ช่วงเวลา
ฉันจะรวมแนวคิดอื่น ๆ ที่กล่าวถึงในโพสต์อื่น ๆ ไว้ด้วยเพื่อการอ้างอิง
รหัสด้านล่าง
แต่ละคอลัมน์ในตารางนี้แสดงถึงกรอบข้อมูลความยาวที่แตกต่างกันซึ่งเราทดสอบแต่ละฟังก์ชั่น 1.0
แต่ละคอลัมน์การแสดงเวลาที่ญาตินำมากับฟังก์ชั่นที่เร็วที่สุดที่กำหนดฐานของดัชนี
res.div(res.min())
10 30 100 300 1000 3000 10000 30000
mask_standard 2.156872 1.850663 2.034149 2.166312 2.164541 3.090372 2.981326 3.131151
mask_standard_loc 1.879035 1.782366 1.988823 2.338112 2.361391 3.036131 2.998112 2.990103
mask_with_values 1.010166 1.000000 1.005113 1.026363 1.028698 1.293741 1.007824 1.016919
mask_with_values_loc 1.196843 1.300228 1.000000 1.000000 1.038989 1.219233 1.037020 1.000000
query 4.997304 4.765554 5.934096 4.500559 2.997924 2.397013 1.680447 1.398190
xs_label 4.124597 4.272363 5.596152 4.295331 4.676591 5.710680 6.032809 8.950255
mask_with_isin 1.674055 1.679935 1.847972 1.724183 1.345111 1.405231 1.253554 1.264760
mask_with_in1d 1.000000 1.083807 1.220493 1.101929 1.000000 1.000000 1.000000 1.144175
คุณจะสังเกตเห็นว่าเวลาที่เร็วที่สุดจะถูกแชร์ระหว่างmask_with_values
และmask_with_in1d
res.T.plot(loglog=True)
ฟังก์ชั่น
def mask_standard(df):
mask = df['A'] == 'foo'
return df[mask]
def mask_standard_loc(df):
mask = df['A'] == 'foo'
return df.loc[mask]
def mask_with_values(df):
mask = df['A'].values == 'foo'
return df[mask]
def mask_with_values_loc(df):
mask = df['A'].values == 'foo'
return df.loc[mask]
def query(df):
return df.query('A == "foo"')
def xs_label(df):
return df.set_index('A', append=True, drop=False).xs('foo', level=-1)
def mask_with_isin(df):
mask = df['A'].isin(['foo'])
return df[mask]
def mask_with_in1d(df):
mask = np.in1d(df['A'].values, ['foo'])
return df[mask]
การทดสอบ
res = pd.DataFrame(
index=[
'mask_standard', 'mask_standard_loc', 'mask_with_values', 'mask_with_values_loc',
'query', 'xs_label', 'mask_with_isin', 'mask_with_in1d'
],
columns=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
dtype=float
)
for j in res.columns:
d = pd.concat([df] * j, ignore_index=True)
for i in res.index:a
stmt = '{}(d)'.format(i)
setp = 'from __main__ import d, {}'.format(i)
res.at[i, j] = timeit(stmt, setp, number=50)
ช่วงเวลา
พิเศษดูกรณีพิเศษเมื่อเรามีวัตถุที่ไม่ใช่วัตถุเดียวdtype
สำหรับกรอบข้อมูลทั้งหมด
รหัสด้านล่าง
spec.div(spec.min())
10 30 100 300 1000 3000 10000 30000
mask_with_values 1.009030 1.000000 1.194276 1.000000 1.236892 1.095343 1.000000 1.000000
mask_with_in1d 1.104638 1.094524 1.156930 1.072094 1.000000 1.000000 1.040043 1.027100
reconstruct 1.000000 1.142838 1.000000 1.355440 1.650270 2.222181 2.294913 3.406735
ปรากฎว่าการสร้างใหม่ไม่คุ้มกับที่ผ่านมาสองสามร้อยแถว
spec.T.plot(loglog=True)
ฟังก์ชั่น
np.random.seed([3,1415])
d1 = pd.DataFrame(np.random.randint(10, size=(10, 5)), columns=list('ABCDE'))
def mask_with_values(df):
mask = df['A'].values == 'foo'
return df[mask]
def mask_with_in1d(df):
mask = np.in1d(df['A'].values, ['foo'])
return df[mask]
def reconstruct(df):
v = df.values
mask = np.in1d(df['A'].values, ['foo'])
return pd.DataFrame(v[mask], df.index[mask], df.columns)
spec = pd.DataFrame(
index=['mask_with_values', 'mask_with_in1d', 'reconstruct'],
columns=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
dtype=float
)
การทดสอบ
for j in spec.columns:
d = pd.concat([df] * j, ignore_index=True)
for i in spec.index:
stmt = '{}(d)'.format(i)
setp = 'from __main__ import d, {}'.format(i)
spec.at[i, j] = timeit(stmt, setp, number=50)
.iloc(numpy.where(..))
เปรียบเทียบในโครงการนี้อย่างไร ii) คุณคาดหวังว่าอันดับจะเหมือนกันเมื่อใช้หลายเงื่อนไขหรือไม่
[{P|EXP}TIME]
- และ[{C|P|EXP}SPACE]
- ค่าใช้จ่ายของการใช้รูปแบบดังกล่าวข้างต้นที่นำเสนอของบล็อกไวยากรณ์ (การประมวลผลด้านบนลง dataframes ทั้งหมดในครั้งเดียว) เติบโตคือเมื่อ ปรับสัดส่วนเป็นบาง~1E6, ~1E9, ~1E12
แถวหรือไม่ ขอบคุณที่แสดงให้เราเห็นภาพรวมทั้งหมดครับ การอ่านค่ามาตรฐานเชิงปริมาณด้วย[min, Avg, MAX, StDev]
ยินดีต้อนรับเสมอเนื่องจากทั้งสองค่าmin
และMAX
มาพร้อมกับการMean/StDev
ผ่อนปรนของแบทช์
หมีแพนด้าเทียบเท่า
select * from table where column_name = some_value
คือ
table[table.column_name == some_value]
หลายเงื่อนไข:
table[(table.column_name == some_value) | (table.column_name2 == some_value2)]
หรือ
table.query('column_name == some_value | column_name2 == some_value2')
import pandas as pd
# Create data set
d = {'foo':[100, 111, 222],
'bar':[333, 444, 555]}
df = pd.DataFrame(d)
# Full dataframe:
df
# Shows:
# bar foo
# 0 333 100
# 1 444 111
# 2 555 222
# Output only the row(s) in df where foo is 222:
df[df.foo == 222]
# Shows:
# bar foo
# 2 555 222
ในรหัสข้างต้นมันเป็นสายdf[df.foo == 222]
ที่ให้แถวตามค่าคอลัมน์222
ในกรณีนี้
เงื่อนไขหลายข้อยังเป็นไปได้:
df[(df.foo == 222) | (df.bar == 444)]
# bar foo
# 1 444 111
# 2 555 222
แต่ ณ จุดนั้นฉันขอแนะนำให้ใช้ฟังก์ชั่นการสืบค้นเนื่องจากมันให้รายละเอียดน้อยกว่าและให้ผลลัพธ์แบบเดียวกัน:
df.query('foo == 222 | bar == 444')
query
เป็นคำตอบเดียวที่นี่ที่เข้ากันได้กับวิธีการผูกมัด ดูเหมือนว่ามันเป็นหมีแพนด้าอนาล็อกfilter
ใน dplyr
[
ไม่ได้ล้อมรอบ(
ด้านนอก
|
เป็นและ แต่แน่นอนมันเป็นหรือผู้ประกอบการ ...
df[condition1][condition2]
df.query('`my col` == 124')
ฉันพบว่าไวยากรณ์ของคำตอบก่อนหน้านี้ซ้ำซ้อนและจดจำยาก Pandas แนะนำquery()
วิธีการใน v0.13 และฉันชอบมันมาก สำหรับคำถามของคุณคุณสามารถทำได้df.query('col == val')
ทำซ้ำจากhttp://pandas.pydata.org/pandas-docs/version/0.17.0/indexing.html#indexing-query
In [167]: n = 10
In [168]: df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc'))
In [169]: df
Out[169]:
a b c
0 0.687704 0.582314 0.281645
1 0.250846 0.610021 0.420121
2 0.624328 0.401816 0.932146
3 0.011763 0.022921 0.244186
4 0.590198 0.325680 0.890392
5 0.598892 0.296424 0.007312
6 0.634625 0.803069 0.123872
7 0.924168 0.325076 0.303746
8 0.116822 0.364564 0.454607
9 0.986142 0.751953 0.561512
# pure python
In [170]: df[(df.a < df.b) & (df.b < df.c)]
Out[170]:
a b c
3 0.011763 0.022921 0.244186
8 0.116822 0.364564 0.454607
# query
In [171]: df.query('(a < b) & (b < c)')
Out[171]:
a b c
3 0.011763 0.022921 0.244186
8 0.116822 0.364564 0.454607
นอกจากนี้คุณยังสามารถเข้าถึงตัวแปรในสภาพแวดล้อมโดยการ@
เพิ่ม
exclude = ('red', 'orange')
df.query('color not in @exclude')
numexpr
ติดตั้งแพ็คเกจเท่านั้น
.query
กับpandas >= 0.25.0
:คำตอบที่อัปเดตในเดือนสิงหาคม 2019
เนื่องจากpandas >= 0.25.0
เราสามารถใช้query
วิธีการกรองดาต้าเฟรมด้วยเมธอดแพนด้าและชื่อคอลัมน์ที่มีช่องว่าง โดยปกติช่องว่างในชื่อคอลัมน์จะให้ข้อผิดพลาด แต่ตอนนี้เราสามารถแก้ไขได้โดยใช้ backtick (`) ดูGitHub :
# Example dataframe
df = pd.DataFrame({'Sender email':['ex@example.com', "reply@shop.com", "buy@shop.com"]})
Sender email
0 ex@example.com
1 reply@shop.com
2 buy@shop.com
ใช้.query
กับวิธีการstr.endswith
:
df.query('`Sender email`.str.endswith("@shop.com")')
เอาท์พุต
Sender email
1 reply@shop.com
2 buy@shop.com
นอกจากนี้เรายังสามารถใช้ตัวแปรท้องถิ่นโดยนำหน้าด้วย@
คำค้นหาของเรา:
domain = 'shop.com'
df.query('`Sender email`.str.endswith(@domain)')
เอาท์พุต
Sender email
1 reply@shop.com
2 buy@shop.com
ผลได้เร็วขึ้นสามารถทำได้โดยใช้numpy.where
ตัวอย่างเช่นด้วยการตั้งค่า unubtu -
In [76]: df.iloc[np.where(df.A.values=='foo')]
Out[76]:
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
การเปรียบเทียบเวลา:
In [68]: %timeit df.iloc[np.where(df.A.values=='foo')] # fastest
1000 loops, best of 3: 380 µs per loop
In [69]: %timeit df.loc[df['A'] == 'foo']
1000 loops, best of 3: 745 µs per loop
In [71]: %timeit df.loc[df['A'].isin(['foo'])]
1000 loops, best of 3: 562 µs per loop
In [72]: %timeit df[df.A=='foo']
1000 loops, best of 3: 796 µs per loop
In [74]: %timeit df.query('(A=="foo")') # slowest
1000 loops, best of 3: 1.71 ms per loop
นี่คือตัวอย่างง่ายๆ
from pandas import DataFrame
# Create data set
d = {'Revenue':[100,111,222],
'Cost':[333,444,555]}
df = DataFrame(d)
# mask = Return True when the value in column "Revenue" is equal to 111
mask = df['Revenue'] == 111
print mask
# Result:
# 0 False
# 1 True
# 2 False
# Name: Revenue, dtype: bool
# Select * FROM df WHERE Revenue = 111
df[mask]
# Result:
# Cost Revenue
# 1 444 111
สำหรับการเลือกคอลัมน์ที่เฉพาะเจาะจงจากหลายคอลัมน์สำหรับค่าที่กำหนดในนุ่น:
select col_name1, col_name2 from table where column_name = some_value.
ตัวเลือก:
df.loc[df['column_name'] == some_value][[col_name1, col_name2]]
หรือ
df.query['column_name' == 'some_value'][[col_name1, col_name2]]
หากต้องการต่อท้ายคำถามที่มีชื่อเสียงนี้ (แม้ว่าจะสายเกินไป): คุณสามารถทำdf.groupby('column_name').get_group('column_desired_value').reset_index()
กรอบข้อมูลใหม่ด้วยคอลัมน์ที่ระบุซึ่งมีค่าเฉพาะ เช่น
import pandas as pd
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split()})
print("Original dataframe:")
print(df)
b_is_two_dataframe = pd.DataFrame(df.groupby('B').get_group('two').reset_index()).drop('index', axis = 1)
#NOTE: the final drop is to remove the extra index column returned by groupby object
print('Sub dataframe where B is two:')
print(b_is_two_dataframe)
เรียกใช้สิ่งนี้ให้:
Original dataframe:
A B
0 foo one
1 bar one
2 foo two
3 bar three
4 foo two
5 bar two
6 foo one
7 foo three
Sub dataframe where B is two:
A B
0 foo two
1 foo two
2 bar two
get_group()
จะส่งคืน dataframe โดยอัตโนมัติ นอกจากนี้คุณก็สามารถพูดว่า "ลดลง = true" reset_index()
เป็นพารามิเตอร์ของ กล่าวอีกนัยหนึ่งก็สามารถย่อให้สั้นลงเป็น: b_is_two_dataframe = df.groupby('B').get_group('two').reset_index(drop=True)
คุณยังสามารถใช้. นำไปใช้:
df.apply(lambda row: row[df['B'].isin(['one','three'])])
ใช้งานได้จริงกับแถว (เช่นใช้ฟังก์ชันกับแต่ละแถว)
ผลลัพธ์คือ
A B C D
0 foo one 0 0
1 bar one 1 2
3 bar three 3 6
6 foo one 6 12
7 foo three 7 14
ผลลัพธ์นั้นเหมือนกับการใช้โดย @unutbu
df[[df['B'].isin(['one','three'])]]