【问题标题】:creating a new dataframe using various values from another dataframe使用来自另一个数据帧的各种值创建一个新的数据帧
【发布时间】:2021-04-14 00:20:05
【问题描述】:

我有一个带有一些参考值的数据框:

ref_value = {A:111, B:222, C:333, D:444}
df = pd.DataFrame(ref_value)

|foo|bar|
|---|---|
|A  |111|
|B  |222|
|C  |333|
|D  |444|

然后我想用它来创建一个更大的数据集,如下所示:

| x | y |
|---|---|
|1  |111|
|2  |111|
|3  |111|
|4  |111|
|5  |111|
|6  |222|
|7  |222|
|8  |222|
|9  |222|
|10 |222|
|11 |333|
|12 |333|
|13 |333|
|14 |333|
|15 |333|
|16 |444|
|17 |444|
|18 |444|
|19 |444|
|20 |444|

这就是我的做法:

new_df = pd.DataFrame(np.arange(20))

new_df.loc[new_df.x <= 5, 'y'] = df.loc[df.foo == 'A', 'bar'].iloc[0]
new_df.loc[(new_df.x > 5) & (new_df.x <= 10), 'y'] = df.loc[df.foo == 'B', 'bar'].iloc[0]
new_df.loc[(new_df.x > 10) & (new_df.x <= 15), 'y'] = df.loc[df.foo == 'C', 'bar'].iloc[0]
new_df.loc[new_df.x > 15, 'y'] = df.loc[df.foo == 'D', 'bar'].iloc[0]

我可以就如何更轻松/优雅地做到这一点提出一些建议吗?

在这种情况下,我似乎无法让 df.apply(lambda x: function) 工作。 注意:我使用的实际 DataFrame 更大一些。

提前致谢。

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

尝试使用 cut 创建映射数据框,注意您可以通过更改 bin 来设置切割点

mapping = pd.DataFrame({'newvalue' : range(1,21),
                        'foo':pd.cut(range(1,21),bins=[0,5,10,15,20],
                              labels=['A','B','C','D'])})
out = mapping.merge(df)
Out[53]: 
    newvalue foo  bar
0          1   A  111
1          2   A  111
2          3   A  111
3          4   A  111
4          5   A  111
5          6   B  222
6          7   B  222
7          8   B  222
8          9   B  222
9         10   B  222
10        11   C  333
11        12   C  333
12        13   C  333
13        14   C  333
14        15   C  333
15        16   D  444
16        17   D  444
17        18   D  444
18        19   D  444
19        20   D  444

【讨论】:

  • 谢谢!这是一个优雅的解决方案,并保持了我更换垃圾箱所需的灵活性。
【解决方案2】:

我认为你可以使用pd.Series.apply如下:

import pandas as pd
import numpy as np
def replace_values(v, ref_values):
    if v <= 5:
        return ref_values["A"]
    elif 5 < v <= 10:
        return ref_values["B"]
    elif 10 < v <= 15:
        return ref_values["C"]
    elif 15 < v:
        return ref_values["D"]
    return np.nan

if __name__ == '__main__':
    ref_value = {"A":111, "B":222, "C":333, "D":444}
    new_df = pd.DataFrame({"x": range(1,21)})
    new_df["y"] = new_df["x"].apply(lambda v: replace_values(v, ref_value))
    print(new_df)

结果:

     x    y
0    1  111
1    2  111
2    3  111
3    4  111
4    5  111
5    6  222
6    7  222
7    8  222
8    9  222
9   10  222
10  11  333
11  12  333
12  13  333
13  14  333
14  15  333
15  16  444
16  17  444
17  18  444
18  19  444
19  20  444

【讨论】:

  • 我最初是在寻找这样的解决方案,但 BENY 的解决方案用更简单的解决方案解决了它。谢谢
【解决方案3】:

这应该可行:

df = df['bar'].repeat(5).reset_index(drop=True)
df.index = df.index+1
df = df.reset_index().set_axis(['x','y'],axis=1)

【讨论】:

    猜你喜欢
    • 2013-08-13
    • 1970-01-01
    • 2016-12-20
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 2021-12-25
    相关资源
    最近更新 更多