สร้าง Dataframe แพนด้าขึ้นมาใหม่
ฉันค่อนข้างใหม่สำหรับ Python ฉันมีปัญหากับการสร้าง Dataframe ที่ไม่ดีขึ้นมาใหม่ Dataframe ของฉันมีลักษณะดังนี้:
df = pd.DataFrame({'col1': ['id 1', 'id 2', 'test 3', 'test 4'],
'col2': ['test 1', 'test 2',
'Number 6135', 'id 4'],
'col3': ['Number 12344', 'Number 21612','id 3','Number 1131']})
อย่างที่คุณเห็นฉันมี "id´s" ในคอลัมน์แรกวินาทีและ Thrid เช่นเดียวกับค่าอื่น ๆ
เป้าหมายของฉันคือการมี Dataframe ซึ่งแต่ละ Col มีเฉพาะค่าที่เริ่มต้นด้วยสตริงย่อยเดียวกันดังตัวอย่างนี้:
ฉันลองใช้สำหรับ Loops แล้วและถ้า Statments เพื่อตรวจสอบว่ามี Substring อยู่ใน String ของฉันหรือไม่ ถ้านั่นเป็นความจริงฉันจะสร้างคอลัมน์ใหม่และเขียนค่าของฉันไว้ข้างใน
for x in df['col1']:
if 'id' in x:
df['newCol']=x
ฉันรู้ว่ารหัสนี้จะไม่สามารถแก้ปัญหาของฉันได้บางทีอาจมีฟังก์ชันแพนด้าบางตัวที่สามารถช่วยฉันแก้ปัญหานี้ได้
หากมีบางอย่างไม่ชัดเจนเพียงแค่ถามฉันว่าฉันจะพยายามอย่างดีที่สุดเพื่ออธิบายปัญหาของฉัน ขอบคุณล่วงหน้าสำหรับความช่วยเหลือของคุณและเป็นเรื่องง่ายสำหรับฉัน :)
คำตอบ
คุณสามารถใช้sorted()กับฟังก์ชั่นคีย์แบบกำหนดเอง:
def key_fn(x):
if 'id' in x:
return 0
if 'test' in x:
return 1
if 'Number' in x:
return 2
return 3
df = df.apply(lambda x: pd.Series(sorted(x, key=key_fn)), axis=1)
df = df.rename(columns=lambda x: 'col{}'.format(x+1))
print(df)
พิมพ์:
col1 col2 col3
0 id 1 test 1 Number 12344
1 id 2 test 2 Number 21612
2 id 3 test 3 Number 6135
3 id 4 test 4 Number 1131
รุ่นอื่นจากความคิดเห็น:
df = pd.DataFrame([sorted(l, key=key_fn) for l in df.values], columns=df.columns)
print(df)
ถ้าเป็นไปได้ทำให้โซลูชันง่ายขึ้นโดยแยกค่าโดยเว้นว่างแรก:
df = (df.reset_index()
.melt('index')
.assign(new = lambda x: x['value'].str.split().str[0])
.pivot('index','new','value'))
print (df)
new Number id test
index
0 Number 12344 id 1 test 1
1 Number 21612 id 2 test 2
2 Number 6135 id 3 test 3
3 Number 1131 id 4 test 4
คุณสามารถใช้Series.str.extract:
L = ['id','test','Number']
df = (df.reset_index()
.melt('index')
.assign(new = lambda x: x['value'].str.extract(f'({"|".join(L)})', expand=False))
.pivot('index','new','value'))
print (df)
new Number id test
index
0 Number 12344 id 1 test 1
1 Number 21612 id 2 test 2
2 Number 6135 id 3 test 3
3 Number 1131 id 4 test 4
ลองสิ่งนี้:
s = df.melt()['value']
df_final = pd.DataFrame({x: s[s.str.startswith(x)].values
for x in s.str.split().str[0].unique()})
Out[27]:
id test Number
0 id 1 test 3 Number 6135
1 id 2 test 4 Number 12344
2 id 4 test 1 Number 21612
3 id 3 test 2 Number 1131
ก่อนอื่นคุณสามารถละลายดาต้าเฟรมจากนั้นใช้numpy selectเพื่อเรียงลำดับชื่อใหม่และสุดท้ายก็หมุน :
(df.melt(ignore_index=False)
.assign(variable=lambda x: np.select([x.value.str.startswith("id"),
x.value.str.startswith("test"),
x.value.str.startswith("Number")],
["col1", "col2", "col3"]))
.reset_index()
.pivot("index", "variable", "value")
.rename_axis(columns=None, index=None))
col1 col2 col3
0 id 1 test 1 Number 12344
1 id 2 test 2 Number 21612
2 id 3 test 3 Number 6135
3 id 4 test 4 Number 1131