<p>这是一个多阶段解决方案,注释中有注释:</p>
<pre><code>import pandas as pd
df = pd.DataFrame(columns=['value', 'name1', '%1', 'name2', '%2', 'name3', '%3'],
data=[[100, 'person1', 0.3, 'person2', 0.5, 'person3', '0.2'],
[100, 'person4', 1], [100, 'person1', 0.6, 'person5', 0.4]])
# Move the name columns below each other in rows
df1 = pd.melt(df, id_vars=['value'], value_vars=['name1', 'name2', 'name3'],
value_name='name')
# Move the percentage columns below each other in rows
df2 = pd.melt(df, id_vars=['value'], value_vars=['%1', '%2', '%3'],
value_name='percentage')
# Some input of percentages was string (note '0.2' in the question);
# let's make it's all float
df2['percentage'] = df2['percentage'].astype(float)
# NaNs are equivalent to zero in this case; easier to calculate with 0.0
df2 = df2.fillna(0)
# We can safely concatenate the two frames, under the assumption that in df1,
# the various name and percentage columns match
df3 = pd.concat([df1, df2], axis=1)
# Remove duplicated columns from the concatenation ('value')
df3 = df3.loc[:, ~df3.columns.duplicated()]
# Calculate the actual procentual values
df3.loc[:, 'value'] = df3['value'] * df3['percentage']
# dropna() will remove any row with a NaN/None anywhere. Since we've already
# replaced the percentages with 0.0, this will drop rows that have a
# 'name' of None
df4 = df3.dropna()
# Select the two relevant columns
df4 = df4[['value', 'name']]
print(df4)
value name
0 30.0 person1
1 100.0 person4
2 60.0 person1
3 50.0 person2
5 40.0 person5
6 20.0 person3
</code></pre>