eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: I have a large pandas DataFrame (160k records, 60 columns of mostly text) but for this example, I have the following DataFrame: df1 = pd.DataFrame([{"GROUP": "A", "COL2": "1", "COL3": "P"}, {"GROUP": "A", "COL2": "2", "COL3": "Q"}, {"GROUP": "A", "COL2": "3", "COL3": "R"}, {"GROUP": "B", "COL2": "4", "COL3": "S"}, {"GROUP": "B", "COL2": "5", "COL3": "T"}, {"GROUP": "B", "COL2": "6", "COL3": "U"}, {"GROUP": "B", "COL2": "7", "COL3": "V"}])  I am trying to create another column that reverses the order of COL2 but only within groups of A and B...so I would expect from top to bottom, the values to be 3,2,1,7,6,5,4. This is achieved with this line of code: df1['REVERSED_COL'] = df1.groupby("GROUP")["COL2"].transform(lambda x: x[::-1])  Instead, I get this:  This line of code worked when I was using Python 3.11.7. However, I recently upgraded to 3.12.3 (and all other modules including pandas to 2.2.1) and removed 3.11.7 interpreter from my machine so I can't go back and test it again. I also have another machine using Python 3.7.4 where the same line of code still works as expected. I tried using the x[::-1] on a list, and that reversed them as expected: This code: x = [1,2,3,4,5,6,7,8,9] print(x) y = x[::-1] print(y)  Results in: [1, 2, 3, 4, 5, 6, 7, 8, 9] [9, 8, 7, 6, 5, 4, 3, 2, 1]  My question is, am I doing something wrong? Is there a different way I can do this? I checked the pandas and python documentation on Python changes and pandas 2.2.1 changes (respectively) but I couldn't find anything relevant enough.

Answer: Because the output of transform is aligned back to the original index when it is a Series, which in your case reverts it back to its original order. To avoid this you must convert to array/list (with values/array/to_numpy): df1['REVERSED_COL'] = (df1.groupby("GROUP")["COL2"] .transform(lambda x: x[::-1].array) )  Output:  GROUP COL2 COL3 REVERSED_COL 0 A 1 P 3 1 A 2 Q 2 2 A 3 R 1 3 B 4 S 7 4 B 5 T 6 5 B 6 U 5 6 B 7 V 4
Question: I have a list of tuples like: tuple_lst = [('foo', 'bar'), ('bar', 'foo'), ('ping', 'pong'), ('pong', 'ping')]  And I want to create a Dataframe with one column containing each tuple pair, like: | one col | | -------- | | ('foo', 'bar') | | ('bar', 'foo') | | ('ping', 'pong') | | ('pong', 'ping') |  I tried: df = pd.DataFrame(tuple_lst, columns='one col')  But this throws an error as it's trying to split the tuples into 2 separate columns. I know if I pass a list of 2 column names here, it would produce a dataframe with 2 columns which is not what I want. I guess I could then put these two columns back together into a list of tuples, but this feels like a lot of work to break them up and put them back together, I feel there must be a simpler way to do this? I need the output to be a dataframe not a series so I can add other columns etc later on.

Answer: Use a dictionary, this will ensure the DataFrame constructor doesn't try to interpret the data as 2D: pd.DataFrame({'one col': tuple_lst})  You could also have used a Series and converted to_frame: pd.Series(tuple_lst).to_frame(name='one col')  Or, closer to your original approach, which could be useful if you have constraints on the format passed to the constructor. Although not as efficient (for small lists): pd.DataFrame(pd.Series(tuple_lst), columns=['one col'])  Output:  one col 0 (foo, bar) 1 (bar, foo) 2 (ping, pong) 3 (pong, ping)  timings For small lists pd.DataFrame(pd.Series(tuple_lst), columns=['one col']) is not as efficient, but for large lists all solutions are equivalent:
Question: I have a list of dicts where each dict can have different keys. I want to create a dataframe with one row where each key is a column and the row is its value: import pandas as pd data = [{"A":1}, {"B":2}, {"C":3}] df = pd.DataFrame(data) print(df.to_string(index=False)) # A B C # 1.0 NaN NaN # NaN 2.0 NaN # NaN NaN 3.0  What I want: # A B C # 1.0 2.0 3.0  How can I drop/compact the rows with NaN values?

Answer: One option would be to stack: df.stack().droplevel(0).to_frame().T  Or using a dummy groupby: import numpy as np df.groupby(np.repeat(0, len(df))).first()  Output:  A B C 0 1.0 2.0 3.0
Question: I’m having some issues joining 2 dataframes using pandas.merge(), based on certain conditions. I would appreciate some advice In the example below, I wish to join the 2 dataframes on customerId. However, I’m interested in only the EARLIEST record in loans_df which matches the condition:  Customers.EndDate < Loans.Date Loans.amount > 100  This means it’s a one-to-one join (or one to zero if no loans exists for a customer). Note: I’m assuming the date convention is yyyymmdd. import pandas as pd Customer_df = pd.DataFrame({ 'CustomerId': [1,2,3], 'End date ': [‘20240101’, ‘20220101’, ‘20250101’] }) Loans_df = pd.DataFrame({ 'LoanId': [1,2,3], 'CustomerId': [1,2,2], ‘Date’: [‘20240112’, ‘20230101’, ‘20240101’], 'Amount': [1000,2000,4000]})   Tried pandas.merge() without success

Answer: It looks like a merge_asof after pre-filtering Loans_df to only keep the values above 100: # prerequisite: ensure correct datetime # Customer_df['End date'] = pd.to_datetime(Customer_df['End date'], format='%Y%m%d') # Loans_df['Date'] = pd.to_datetime(Loans_df['Date'], format='%Y%m%d') out = pd.merge_asof(Customer_df.sort_values(by='End date'), Loans_df.query('Amount > 100').sort_values(by='Date'), left_on='End date', right_on='Date', by='CustomerId', direction='forward' )  Output:  CustomerId End date LoanId Date Amount 0 2 2022-01-01 2.0 2023-01-01 2000.0 1 1 2024-01-01 1.0 2024-01-12 1000.0 2 3 2025-01-01 NaN NaT NaN  If you only want the matches, add a dropna: out = (pd.merge_asof(Customer_df.sort_values(by='End date'), Loans_df.query('Amount > 100').sort_values(by='Date'), left_on='End date', right_on='Date', by='CustomerId', direction='forward') .dropna(subset=['Date']) )  Output:  CustomerId End date LoanId Date Amount 0 2 2022-01-01 2.0 2023-01-01 2000.0 1 1 2024-01-01 1.0 2024-01-12 1000.0
Question: Python novice here. I have the following nested tuple containing values, sides and context: my_tuple = [(121, 131, 174, 188, 228, 242, 282), ('Left', 'Right', 'Right', 'Left', 'Left', 'Right', 'Right'), ('Foot Strike', 'Foot Off', 'Foot Strike', 'Foot Off', 'Foot Strike', 'Foot Off', 'Foot Strike')]  I would like to extract the values which agree with 'Right' AND 'Foot Strike' (i.e. val = 174 & 282). I know I could extract the first indices of all subtuples by using first = [lis[0] for lis in my_tuple]  and subsequently select the first vaule of that tuple, but I am failing to correctly set conditional values to go with this selection. Thank your for helping out the newbie!

Answer: out = (el[0] for el in zip(*my_tuple) if el[1]=='Right' and el[2]=='Foot Strike')  Explanation: First, we use zip to obtain iterable of (value, side, context) tuples. Then we can go through that iterable, filter on our condition and return first element of each tuple. Output: print(list(out)) [174, 282]
Question: There are multiple questions on StackOverflow, asking how the comma syntax works, but most of them refer to m[:,n] which refers to the nth column. Similarly, m[n,:] refers to the nth row. I find this method of slicing used in the labs of Machine Learning Specialization by Andrew Ng. But does this slicing have any advantage over m[n]?

Answer: For an array with 2 or more dimensions, m[n] and m[n, :] are identical. The first can be considered shorthand for the second. For an array with 1 dimension, m[n] will return element n, and m[n, :] will result in an error. I personally would choose m[n, :] in some cases to make the code more human-readable: for example, when you know that m is two-dimensional, then m[n, :] immediately implies this to the reader, whereas m[n] might leave them having to guess at whether m is 1D or 2D.
Question: My DataFrame: import pandas as pd df = pd.DataFrame( { 'group': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'e', 'e', 'e'], 'num': [1, 2, 3, 1, 12, 12, 13, 2, 4, 2, 5, 6, 10, 20, 30] } )  Expected output is getting three groups from above df  group num 0 a 1 1 a 2 2 a 3 group num 6 c 13 7 c 2 8 c 4 group num 12 e 10 13 e 20 14 e 30  Logic: I want to compare the first value of each group to the last cummax of num column. I can explain better by this code: df['last_num'] = df.groupby('group')['num'].tail(1) df['last_num'] = df.last_num.ffill().cummax()  But I think what I really need is this desired_cummax:  group num last_num desired_cummax 0 a 1 NaN 3 1 a 2 NaN 3 2 a 3 3.0 3 3 b 1 3.0 3 4 b 12 3.0 3 5 b 12 12.0 3 6 c 13 12.0 3 7 c 2 12.0 3 8 c 4 12.0 4 9 d 2 12.0 4 10 d 5 12.0 4 11 d 6 12.0 4 12 e 10 12.0 4 13 e 20 12.0 4 14 e 30 30.0 30  I don't want a new cummax if the first value of num for each group is less than last_num. For example for group b, the first value of num is 1. Since it is less that its last_num, when it reaches the end of the group b it should not put 12. It should still be 3. Now for group c, since its first value is more than last_num, when it reaches at the end of group c, a new cummax will be set. After that I want to filter the groups. If df.num.iloc[0] > df.desired_cummax.iloc[0] Note that the first group should be in the expected output no matter what. Maybe there is a better approach to solve this. But this is what I have thought might work. My attempt was creating last_num but I don't know how to continue.

Answer: IIUC, you can aggregate as first/last per group, mask the unwanted values and map back to the group. Finally shift one row up: tmp = df.groupby('group')['num'].agg(['first', 'last']) s = tmp['last'].where(tmp['last'].shift(fill_value=0).le(tmp['first'])).ffill().cummax() df['desired_cummax'] = df['group'].map(s.shift().bfill()).shift(-1).fillna(df['num'])  Output:  group num desired_cummax 0 a 1 3.0 1 a 2 3.0 2 a 3 3.0 3 b 1 3.0 4 b 12 3.0 5 b 12 3.0 6 c 13 3.0 7 c 2 3.0 8 c 4 4.0 9 d 2 4.0 10 d 5 4.0 11 d 6 4.0 12 e 10 4.0 13 e 20 4.0 14 e 30 30.0  Intermediates: # computation of the mapping Series "s" first last last.shift(fill_value=0) .le(tmp['first']) where .ffill() group a 1 3 0 True 3.0 3.0 b 1 12 3 False NaN 3.0 c 13 4 12 True 4.0 4.0 d 2 6 4 False NaN 4.0 e 10 30 6 True 30.0 30.0 # shifting before mapping s s.shift() .bfill() group a 3.0 NaN 3.0 b 3.0 3.0 3.0 c 4.0 3.0 3.0 d 4.0 4.0 4.0 e 30.0 4.0 4.0 # mapping group map .shift(-1) .fillna(df['num']) 0 a 3.0 3.0 3.0 1 a 3.0 3.0 3.0 2 a 3.0 3.0 3.0 3 b 3.0 3.0 3.0 4 b 3.0 3.0 3.0 5 b 3.0 3.0 3.0 6 c 3.0 3.0 3.0 7 c 3.0 3.0 3.0 8 c 3.0 4.0 4.0 9 d 4.0 4.0 4.0 10 d 4.0 4.0 4.0 11 d 4.0 4.0 4.0 12 e 4.0 4.0 4.0 13 e 4.0 4.0 4.0 14 e 4.0 NaN 30.0
Question: Say I have this: import polars as pl import polars.selectors as cs df = pl.select( j = pl.int_range(10, 99).sample(10, with_replacement=True), k = pl.int_range(10, 99).sample(10, with_replacement=True), l = pl.int_range(10, 99).sample(10, with_replacement=True), )  shape: (10, 3) ┌─────┬─────┬─────┐ │ j ┆ k ┆ l │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 71 ┆ 79 ┆ 67 │ │ 26 ┆ 42 ┆ 55 │ │ 12 ┆ 43 ┆ 85 │ │ 92 ┆ 96 ┆ 14 │ │ 95 ┆ 26 ┆ 62 │ │ 75 ┆ 14 ┆ 56 │ │ 61 ┆ 41 ┆ 75 │ │ 74 ┆ 97 ┆ 70 │ │ 73 ┆ 32 ┆ 10 │ │ 66 ┆ 98 ┆ 40 │ └─────┴─────┴─────┘  and I want to apply the same when/then/otherwise condition on multiple columns: df.select( pl.when(cs.numeric() < 50) .then(1) .otherwise(2) )  This fails with: DuplicateError: the name 'literal' is duplicate  How do I make this use the currently selected column as the alias? I.e. I want the equivalent of this: df.select( pl.when(pl.col(c) < 50) .then(1) .otherwise(2) .alias(c) for c in df.columns )  shape: (10, 3) ┌─────┬─────┬─────┐ │ j ┆ k ┆ l │ │ --- ┆ --- ┆ --- │ │ i32 ┆ i32 ┆ i32 │ ╞═════╪═════╪═════╡ │ 2 ┆ 2 ┆ 2 │ │ 1 ┆ 1 ┆ 2 │ │ 1 ┆ 1 ┆ 2 │ │ 2 ┆ 2 ┆ 1 │ │ 2 ┆ 1 ┆ 2 │ │ 2 ┆ 1 ┆ 2 │ │ 2 ┆ 1 ┆ 2 │ │ 2 ┆ 2 ┆ 2 │ │ 2 ┆ 1 ┆ 1 │ │ 2 ┆ 2 ┆ 1 │ └─────┴─────┴─────┘ 

Answer: You can use .name.keep() df.select( pl.when(cs.numeric() < 50) .then(1) .otherwise(2) .name.keep() )  shape: (10, 3) ┌─────┬─────┬─────┐ │ j ┆ k ┆ l │ │ --- ┆ --- ┆ --- │ │ i32 ┆ i32 ┆ i32 │ ╞═════╪═════╪═════╡ │ 1 ┆ 1 ┆ 2 │ │ 2 ┆ 1 ┆ 1 │ │ 1 ┆ 2 ┆ 1 │ │ 2 ┆ 2 ┆ 1 │ │ 2 ┆ 1 ┆ 2 │ │ 2 ┆ 2 ┆ 2 │ │ 2 ┆ 2 ┆ 1 │ │ 2 ┆ 2 ┆ 2 │ │ 1 ┆ 1 ┆ 2 │ │ 2 ┆ 2 ┆ 1 │ └─────┴─────┴─────┘
Question: I am trying to change the List of Values of a Taipy selector at runtime, but I keep failing. My lov is defined as the keys of a dictionary in my application, called shapes. I define my selector like this: tgb.selector(value="{sel_shape}", lov=list(shapes.keys()), dropdown=True, label="Shapes")  At startup, the default values are loaded correctly. However, I need to be able to change the selector lov when I manipulate the shapes dictionary at runtime. How can I achieve that? Here's what I tried so far. Update the shapes dictionary Simply updating the dictionary (e.g. adding a new key shapes['new_shape'] = [1, 2, 3]) does not work, as the selector lov does not seem to be a dynamic property. Define the lov in a state variable I redefined the selector as tgb.selector(value="{sel_shape}", lov="{selector_lov}", dropdown=True, label="Shapes") and defined a module global variable selector_lov = shapes.keys(). Then, manipulating the shapes dictionary has no effect on the selector lov. Reload the page Every time I manipulate the dictionary I make sure to reload the local page (navigate(state, to="emitter", force=True)). In my top module I have:  def on_navigate(state, page_name, params): if page_name == "emitter": state.selector_lov = state.shapes.keys()  Still no change in the selector lov after editing shapes.

Answer: Try this syntax: tgb.selector(value="{sel_shape}", lov="{list(shapes.keys())}", dropdown=True, label="Shapes")  Here is a full example: from taipy.gui import Gui import taipy.gui.builder as tgb shapes = {"Mail":["example@example", "example2@example"], "Person":["John Doe", "Jane Doe"]} selected_shape = None def add_shape(state): state.shapes["Skill"] = ["Python", "R"] with tgb.Page() as page: tgb.selector("{selected_shape}", lov="{list(shapes.keys())}", dropdown=True) tgb.button("Add a new shape", on_action=add_shape) Gui(page).run()  You normally don't have to navigate to the page and reload it. You could have used a LOV variable as you mentioned: from taipy.gui import Gui import taipy.gui.builder as tgb shapes = {"Mail":["example@example", "example2@example"], "Person":["John Doe", "Jane Doe"]} shapes_lov = list(shapes.keys()) selected_shape = None def add_shape(state): state.shapes["Skill"] = ["Python", "R"] state.shapes_lov = list(state.shapes.keys()) with tgb.Page() as page: tgb.selector("{selected_shape}", lov="{shapes_lov}", dropdown=True) tgb.button("Add a new shape", on_action=add_shape) Gui(page).run()  Also, note that usually, changes are propagated to the state when having a direct assignment. state.shapes = new_value and not by doing state.shapes["Skill"] = ["Python", "R"]. Here it is working because this kind of assignment are supported by Taipy for dictionary.
Question: According to the PEP 484's "Using None" part:  When used in a type hint, the expression None is considered equivalent to type(None).  However, I encountered a case where both don't seem equivalent : from typing import Callable, NamedTuple, Type, Union # I define a set of available return types: ReturnType = Union[ int, None, ] # I use this Union type to define other types, like this callable type. SomeCallableType = Callable[..., ReturnType] # But I also want to store some functions metadata (including the function's return type) in a `NamedTuple`: class FuncInfos(NamedTuple): return_type: Type[ReturnType] # This works fine: fi_1 = FuncInfos(return_type=int) # But this issues an error: # main.py:21: error: Argument "return_type" to "FuncInfos" has incompatible type "None"; expected "type[int] | type[None]" [arg-type] # Found 1 error in 1 file (checked 1 source file) fi_2 = FuncInfos(return_type=None) # But this works fine: fi_3 = FuncInfos(return_type=type(None))  It doesn't pose me much problem to write type(None) rather than simply None, but I would've liked to understand the above error issued that seems to contradict the quote from PEP 484. Snippet available for execution here.  EDIT: It actually seems to boil down to the following: from typing import Type a: Type[None] # This seems to cause an issue: # main.py:4: error: Incompatible types in assignment (expression has type "None", variable has type "type[None]") [assignment] # Found 1 error in 1 file (checked 1 source file) a = None # This seems to work: a = type(None)  Snippet available for execution here.

Answer: As showed in the post, the PEP 484 stated something ambiguous:  When used in a type hint, the expression None is considered equivalent to type(None).  But I found out about the PEP 483 that uses a much clearer wording in its Pragmatics:  Where a type is expected, None can be substituted for type(None); e.g. Union[t1, None] == Union[t1, type(None)].  With that in mind, different examples now start to make sense. For instance, my second MRE: from typing import Type a: Type[None] # This seems to cause an issue: # main.py:4: error: Incompatible types in assignment (expression has type "None", variable has type "type[None]") [assignment] # Found 1 error in 1 file (checked 1 source file) a = None # This seems to work: a = type(None)  now can be interpreted as: from typing import Type a: Type[type(None)] # Type[...] expects a type. a = None a = type(None)  Now, a's type is explicitly "subtype of type(None)", which precisely doesn't match the type of the expression None, hence the error message. However, it's indeed the type of the second expression: type(None) ("Every type is a subtype of itself." according to the PEP 483 itself).  So, as suggested by some comments, I basically misinterpreted the PEP 484 and forgot that the "equivalence" took effect only "in a type hint" (or "where a type is expected"). Which wasn't the case when passing parameters or making assignments in my snippets.
Question: After reading the documentation seems like it uses forward difference as its approximation method, but I can't see any direct way to make it use other method or a custom one. Using the tools in the documentation I tried this to make it use a custom method and did this implementation to test if the results were the same: import numpy as np from scipy.optimize import newton_krylov from scipy.sparse.linalg import LinearOperator # Function def uniform_problem(x, A, b): return b - A@x size = 12 A = np.random.uniform(-1, 1, size=(size, size)) b = np.random.uniform(-1, 1, size=(size, )) xr = np.random.uniform(-1, 1, size=(size, ))# root x0 = np.random.uniform(-1, 1, size=(size, ))# initial guess F = lambda x: uniform_problem(x, A, b) - uniform_problem(xr, A, b) #Arbitrary parameters max_iter = 10 tol = 1e-3 h = 1e-4 repeats = 5000  # Using own implementation of Forward Difference def get_jacobian_vector_product_fdf(F, x, v, h=1e-5): step = h * v return (F(x + step) - F(x)) / h error1 = 0 for i in range(repeats): x = x0.copy() lambdaJv = lambda v: get_jacobian_vector_product_fdf(F, x, v, h) linear_operator = LinearOperator((size, size), matvec=lambdaJv) solution1 = newton_krylov(F, x, method="gmres", inner_maxiter=max_iter, iter=max_iter, callback=None, f_tol=tol, rdiff=h, inner_M=linear_operator) error1 += np.linalg.norm(F(solution1)) error1 /= repeats print(error1) # aprox 1.659173186802721  # Using no custom method error2 = 0 for i in range(repeats): x = x0.copy() solution2 = newton_krylov(F, x, method="gmres", inner_maxiter=max_iter, iter=max_iter, callback=None, f_tol=tol, rdiff=h) error2 += np.linalg.norm(F(solution2)) error2 /= repeats print(error2) # aprox 0.024629534404425796  print(error1/error2) # Orders of magnitude of difference  I expected to get the same results, but they are clearly different. I think I'm having trouble understanding what the tools of the documentation do.

Answer: I misunderstood, the 'inner_M' parameter does not do what I thought it did, but I found a solution by creating a custom scipy Jacobian class following the same implementation scipy does. import numpy as np import scipy.sparse.linalg from scipy.linalg import norm import scipy.optimize._nonlin from scipy.optimize._nonlin import Jacobian, _nonlin_wrapper # Create your jacobian class using the scipy Jacobian interface. class KrylovJacobianCustom(Jacobian): #... code of custom jacobian ... # (In my case, a variant of the Krylov one) # Make your class visible to the scipy scope. scipy.optimize._nonlin.KrylovJacobianCustom = KrylovJacobianCustom # Define your function using the scipy non linear wrapper. newton_krylov_custom = _nonlin_wrapper('newton_krylov_custom', scipy.optimize._nonlin.KrylovJacobianCustom)  This way, this function behaves the same as newton_krylov() or any other non linear solver, but will instead use your implementation of the Jacobian class in the computation. Example: def fun(x): return [x[0] + 0.5 * x[1] - 1.0, 0.5 * (x[1] - x[0]) ** 2] sol = newton_krylov_custom(fun, [0, 0]) >> array([0.66731771, 0.66536458])
Question: I have this bit for parsing some output from stdout: out_lines = res.stdout.split("\n") out_lines = [e.split() for e in out_lines] out_vals = [{"date":e[0], "time":e[1], "size":e[2], "name":e[3]} for e in out_lines if e]  Is there an idiomatic way to merge the second and third lines here so that the splitting and mapping happen within the same line, without redundant calls to e.split()?

Answer: @trincot's answer works but can avoid a post-processing filter by mapping the lines to str.split so that the filtering can be done with the if clause of the comprehension instead: out_vals = [ dict(zip(("date", "time", "size", "name"), e)) for e in map(str.split, res.stdout.split("\n")) if e ]
Question: Knowing a final number (for example 5), I would like to create an array containing the following sequence: [0,1,1,2,2,3,3,4,4,5] Meaning that the list should contain all numbers repeated twice, except for the first and last. Here is the code I use to achieve this :  import numpy as np # final number last = 35 # first sequence sa = np.arange(0,last,1) # second sequence (shifted by 1 unit) sb = np.arange (1,last+1,1) # concatenation and flattening sequence = np.stack((sa, sb), axis=1).ravel() # view the result print(sequence)  Do you think there would be a more direct and/or effective way to achieve the same result?

Answer: What about using arange on 2*N, add 1 and take the floor division by 2? N = 5 out = (np.arange(2*N)+1)//2 # or variant suggested by @TlsChris # out = (np.arange(2*N)+1)>>1  Alternatively, with repeat and excluding the first/last: out = np.repeat(np.arange(N+1), 2)[1:-1]  Or with broadcasting: out = (np.arange(N)[:, None]+[0, 1]).ravel()  Output: array([0, 1, 1, 2, 2, 3, 3, 4, 4, 5]) timings Comparison of the different answers  Relative timings, around 10,000 items, the original answer seems to be the most efficient, otherwise np.repeat(np.arange(N+1), 2)[1:-1] is the fastest: